r311851 - Don't see through 'using member-declarations' when determining the relation of any potential implicit object expression to the parent class of the member function containing the function call.

Faisal Vali via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 27 09:49:47 PDT 2017


Author: faisalv
Date: Sun Aug 27 09:49:47 2017
New Revision: 311851

URL: http://llvm.org/viewvc/llvm-project?rev=311851&view=rev
Log:
Don't see through 'using member-declarations' when determining the relation of any potential implicit object expression to the parent class of the member function containing the function call.

Prior to this patch clang would not error here:

  template <class T> struct B;
  
  template <class T> struct A {
    void foo();
    void foo2();
    
    void test1() {
      B<T>::foo();  // OK, foo is declared in A<int> - matches type of 'this'.
      B<T>::foo2(); // This should be an error!  
                    // foo2 is found in B<int>, 'base unrelated' to 'this'.
    }
  };

  template <class T> struct B : A<T> {
    using A<T>::foo2;
  };


Modified:
    cfe/trunk/lib/Sema/SemaExprMember.cpp
    cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=311851&r1=311850&r2=311851&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Sun Aug 27 09:49:47 2017
@@ -102,15 +102,15 @@ static IMAKind ClassifyImplicitMemberAcc
   bool hasNonInstance = false;
   bool isField = false;
   BaseSet Classes;
-  for (NamedDecl *D : R) {
-    // Look through any using decls.
-    D = D->getUnderlyingDecl();
-
+  for (const NamedDecl *const D : R) {   
     if (D->isCXXInstanceMember()) {
-      isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
-                 isa<IndirectFieldDecl>(D);
+      // Look through any using decls.
+      const NamedDecl *const UnderlyingDecl = D->getUnderlyingDecl();
+      isField |= isa<FieldDecl>(UnderlyingDecl) ||
+                 isa<MSPropertyDecl>(UnderlyingDecl) ||
+                 isa<IndirectFieldDecl>(UnderlyingDecl);
 
-      CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
+      const CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
       Classes.insert(R->getCanonicalDecl());
     } else
       hasNonInstance = true;

Modified: cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp?rev=311851&r1=311850&r2=311851&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp Sun Aug 27 09:49:47 2017
@@ -64,17 +64,26 @@ namespace test2 {
 
   template <class T> struct A {
     void foo();
-
+    void foo2();
+    static void static_foo();
+    static void static_foo2();
+    
     void test0() {
       Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
     }
 
     void test1() {
       B<T>::foo();
+      B<T>::foo2(); // expected-error {{call to non-static member function without an object argument}}
+      B<T>::static_foo();
+      B<T>::static_foo2();
     }
 
     static void test2() {
       B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
+      B<T>::foo2(); // expected-error {{call to non-static member function without an object argument}}
+      B<T>::static_foo();
+      B<T>::static_foo2();
     }
 
     void test3() {
@@ -83,15 +92,17 @@ namespace test2 {
   };
 
   template <class T> struct B : A<T> {
+    using A<T>::foo2;
+    using A<T>::static_foo2;
   };
-
+  
   template <class T> struct C {
   };
 
   int test() {
     A<int> a;
     a.test0(); // no instantiation note here, decl is ill-formed
-    a.test1();
+    a.test1(); // expected-note {{in instantiation}}
     a.test2(); // expected-note {{in instantiation}}
     a.test3(); // expected-note {{in instantiation}}
   }




More information about the cfe-commits mailing list