]> granicus.if.org Git - clang/commitdiff
[ms] Prevent explicit constructor name lookup if scope is missing
authorWill Wilson <will@indefiant.com>
Thu, 25 Oct 2018 11:45:32 +0000 (11:45 +0000)
committerWill Wilson <will@indefiant.com>
Thu, 25 Oct 2018 11:45:32 +0000 (11:45 +0000)
MicrosoftExt allows explicit constructor calls. Prevent lookup of constructor name unless the name has explicit scope.
This avoids a compile-time crash due to confusing a member access for a constructor name.

Test case included. All tests pass.

Differential Revision: https://reviews.llvm.org/D53441

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345258 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseExpr.cpp
test/SemaCXX/MicrosoftCompatibility.cpp

index b9028bffa1549058fb074383e622e0303187dfb8..54733d8733afd272e9deb5c528b5e02b4b4dac1b 100644 (file)
@@ -1809,7 +1809,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
                                     /*EnteringContext=*/false,
                                     /*AllowDestructorName=*/true,
                                     /*AllowConstructorName=*/
-                                      getLangOpts().MicrosoftExt,
+                                    getLangOpts().MicrosoftExt &&
+                                        SS.isNotEmpty(),
                                     /*AllowDeductionGuide=*/false,
                                     ObjectType, &TemplateKWLoc, Name)) {
         (void)Actions.CorrectDelayedTyposInExpr(LHS);
index 203a810111426e2200b072a32e423387ecf0c3f8..727e67528fa0bb8d0326750d284f894bded9d4eb 100644 (file)
@@ -302,3 +302,23 @@ void function_to_voidptr_conv() {
   void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}}
   void *a3 = function_ptr;        // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}}
 }
+
+namespace member_lookup {
+
+template<typename T>
+struct ConfuseLookup {
+  T* m_val;
+  struct m_val {
+    static size_t ms_test;
+  };
+};
+
+// Microsoft mode allows explicit constructor calls
+// This could confuse name lookup in cases such as this
+template<typename T>
+size_t ConfuseLookup<T>::m_val::ms_test
+  = size_t(&(char&)(reinterpret_cast<ConfuseLookup<T>*>(0)->m_val));
+
+void instantiate() { ConfuseLookup<int>::m_val::ms_test = 1; }
+}
+