r250839 - Look through using decls when classifying implicit member access

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 20 11:12:09 PDT 2015


Author: rnk
Date: Tue Oct 20 13:12:08 2015
New Revision: 250839

URL: http://llvm.org/viewvc/llvm-project?rev=250839&view=rev
Log:
Look through using decls when classifying implicit member access

Clang will now accept this valid C++11 code:
  struct A { int field; };
  struct B : A {
    using A::field;
    enum { TheSize = sizeof(field) };
  };

Previously we would classify the 'field' reference as something other
than a field, and then forget to apply the C++11 rule to allow
non-static data member references in unevaluated contexts.

This usually arises in class templates that want to reference fields of
a dependent base in an unevaluated context outside of an instance
method. Such contexts do not allow references to 'this', so the only way
to access the field is with a using decl and an implicit member
reference.

Modified:
    cfe/trunk/lib/Sema/SemaExprMember.cpp
    cfe/trunk/test/SemaCXX/using-decl-1.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=250839&r1=250838&r2=250839&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Tue Oct 20 13:12:08 2015
@@ -102,8 +102,9 @@ static IMAKind ClassifyImplicitMemberAcc
   bool hasNonInstance = false;
   bool isField = false;
   BaseSet Classes;
-  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
-    NamedDecl *D = *I;
+  for (NamedDecl *D : R) {
+    // Look through any using decls.
+    D = D->getUnderlyingDecl();
 
     if (D->isCXXInstanceMember()) {
       isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
@@ -111,8 +112,7 @@ static IMAKind ClassifyImplicitMemberAcc
 
       CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
       Classes.insert(R->getCanonicalDecl());
-    }
-    else
+    } else
       hasNonInstance = true;
   }
 

Modified: cfe/trunk/test/SemaCXX/using-decl-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-1.cpp?rev=250839&r1=250838&r2=250839&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp Tue Oct 20 13:12:08 2015
@@ -327,3 +327,16 @@ namespace PR24033 {
     using PR24033::st; // expected-error {{target of using declaration conflicts with declaration already in scope}}
   }
 }
+
+namespace field_use {
+struct A { int field; };
+struct B : A {
+  // Previously Clang rejected this valid C++11 code because it didn't look
+  // through the UsingShadowDecl.
+  using A::field;
+#if __cplusplus < 201103L
+  // expected-error at +2 {{invalid use of non-static data member 'field'}}
+#endif
+  enum { X = sizeof(field) };
+};
+}




More information about the cfe-commits mailing list