]> granicus.if.org Git - clang/commitdiff
When creating an implicit member expression through a qualified-id, check that the...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 14 Apr 2011 00:46:47 +0000 (00:46 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 14 Apr 2011 00:46:47 +0000 (00:46 +0000)
named by the nested-name-specifier is same or base of the class in which the member expression appears.

It seems we also had an ill-formed test case, mon dieu! Fixes rdar://8576107.

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

lib/Sema/SemaExpr.cpp
test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp

index eb84cff99929312ee2eede344d911ffb84675029..8ccb9b8180443590aee4f750b42dc31ea12e8c25 100644 (file)
@@ -1318,12 +1318,24 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
     return IMA_Error_StaticContext;
   }
 
+  CXXRecordDecl *
+        contextClass = cast<CXXMethodDecl>(DC)->getParent()->getCanonicalDecl();
+
+  // [class.mfct.non-static]p3: 
+  // ...is used in the body of a non-static member function of class X,
+  // if name lookup (3.4.1) resolves the name in the id-expression to a
+  // non-static non-type member of some class C [...]
+  // ...if C is not X or a base class of X, the class member access expression
+  // is ill-formed.
+  if (R.getNamingClass() &&
+      contextClass != R.getNamingClass()->getCanonicalDecl() &&
+      contextClass->isProvablyNotDerivedFrom(R.getNamingClass()))
+    return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
+
   // If we can prove that the current context is unrelated to all the
   // declaring classes, it can't be an implicit member reference (in
   // which case it's an error if any of those members are selected).
-  if (IsProvablyNotDerivedFrom(SemaRef,
-                               cast<CXXMethodDecl>(DC)->getParent(),
-                               Classes))
+  if (IsProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
     return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
 
   return (hasNonInstance ? IMA_Mixed : IMA_Instance);
index c81e4ef1b1b873d439265e2383916c63807d06d8..9116e7146f812a339c597b4df2f0eff8f259d6ab 100644 (file)
@@ -35,17 +35,22 @@ namespace test1 {
   struct A {
     void foo(Opaque1); // expected-note {{candidate}}
     void foo(Opaque2); // expected-note {{candidate}}
-    void test();
   };
 
   struct B : A {
-    
+    void test();
   };
 
-  void A::test() {
-    B::foo(Opaque1());
-    B::foo(Opaque2());
-    B::foo(Opaque3()); // expected-error {{no matching member function}}
+  struct C1 : A { };
+  struct C2 : B { };
+
+  void B::test() {
+    A::foo(Opaque1());
+    A::foo(Opaque2());
+    A::foo(Opaque3()); // expected-error {{no matching member function}}
+
+    C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
+    C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
   }
 }