]> granicus.if.org Git - clang/commitdiff
PR11956: C++11's special exception for accessing non-static data members from
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Feb 2012 10:04:07 +0000 (10:04 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Feb 2012 10:04:07 +0000 (10:04 +0000)
unevaluated operands applies within member functions, too.

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

lib/Sema/SemaExprMember.cpp
test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp

index 54296942d0d4bcb7c90f65795c739e80d44bbe4d..e90d6e1bc9882968c1cbb7e887db20161f656930 100644 (file)
@@ -138,25 +138,25 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
   if (Classes.empty())
     return IMA_Static;
 
+  if (SemaRef.getLangOptions().CPlusPlus0x && isField) {
+    // C++11 [expr.prim.general]p12:
+    //   An id-expression that denotes a non-static data member or non-static
+    //   member function of a class can only be used:
+    //   (...)
+    //   - if that id-expression denotes a non-static data member and it
+    //     appears in an unevaluated operand.
+    const Sema::ExpressionEvaluationContextRecord& record
+      = SemaRef.ExprEvalContexts.back();
+    if (record.Context == Sema::Unevaluated)
+      return IMA_Field_Uneval_Context;
+  }
+
   // If the current context is not an instance method, it can't be
   // an implicit member reference.
   if (isStaticContext) {
     if (hasNonInstance)
-        return IMA_Mixed_StaticContext;
-        
-    if (SemaRef.getLangOptions().CPlusPlus0x && isField) {
-      // C++11 [expr.prim.general]p12:
-      //   An id-expression that denotes a non-static data member or non-static
-      //   member function of a class can only be used:
-      //   (...)
-      //   - if that id-expression denotes a non-static data member and it
-      //     appears in an unevaluated operand.
-      const Sema::ExpressionEvaluationContextRecord& record
-        = SemaRef.ExprEvalContexts.back();
-      if (record.Context == Sema::Unevaluated)
-        return IMA_Field_Uneval_Context;
-    }
-    
+      return IMA_Mixed_StaticContext;
+
     return IMA_Error_StaticContext;
   }
 
index 59c8660aa18a10e9adfe6c40393ccf295cd8c6e9..606300b1b2ff755ebd1e17d3a831edf32918e32b 100644 (file)
@@ -27,4 +27,12 @@ namespace std {
 class Poly { virtual ~Poly(); };
 const std::type_info& k = typeid(S::m);
 const std::type_info& m = typeid(*(Poly*)S::m); // expected-error {{invalid use of nonstatic data member}}
-const std::type_info& n = typeid(*(Poly*)(0*sizeof S::m)); 
\ No newline at end of file
+const std::type_info& n = typeid(*(Poly*)(0*sizeof S::m)); 
+
+namespace PR11956 {
+  struct X { char a; };
+  struct Y { int f() { return sizeof(X::a); } }; // ok
+
+  struct A { enum E {} E; };
+  struct B { int f() { return sizeof(A::E); } }; // ok
+}