[cfe-commits] r120182 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/CXX/class/class.nest/p1.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Fri Nov 26 08:28:07 PST 2010


Author: cornedbee
Date: Fri Nov 26 10:28:07 2010
New Revision: 120182

URL: http://llvm.org/viewvc/llvm-project?rev=120182&view=rev
Log:
Allow access to non-static members without an object in sizeof expressions, in C++0x. Patch by Jakub Wieczorek.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/CXX/class/class.nest/p1.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=120182&r1=120181&r2=120182&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Nov 26 10:28:07 2010
@@ -1038,11 +1038,15 @@
 
   // Collect all the declaring classes of instance members we find.
   bool hasNonInstance = false;
+  bool hasField = false;
   llvm::SmallPtrSet<CXXRecordDecl*, 4> Classes;
   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
     NamedDecl *D = *I;
 
     if (D->isCXXInstanceMember()) {
+      if (dyn_cast<FieldDecl>(D))
+        hasField = true;
+
       CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
       Classes.insert(R->getCanonicalDecl());
     }
@@ -1057,8 +1061,24 @@
 
   // If the current context is not an instance method, it can't be
   // an implicit member reference.
-  if (isStaticContext)
-    return (hasNonInstance ? IMA_Mixed_StaticContext : IMA_Error_StaticContext);
+  if (isStaticContext) {
+    if (hasNonInstance)
+        return IMA_Mixed_StaticContext;
+        
+    if (SemaRef.getLangOptions().CPlusPlus0x && hasField) {
+      // C++0x [expr.prim.general]p10:
+      //   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();
+      bool isUnevaluatedExpression = record.Context == Sema::Unevaluated;
+      if (isUnevaluatedExpression)
+        return IMA_Mixed_StaticContext;
+    }
+    
+    return IMA_Error_StaticContext;
+  }
 
   // If we can prove that the current context is unrelated to all the
   // declaring classes, it can't be an implicit member reference (in

Modified: cfe/trunk/test/CXX/class/class.nest/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.nest/p1.cpp?rev=120182&r1=120181&r2=120182&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.nest/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.nest/p1.cpp Fri Nov 26 10:28:07 2010
@@ -3,12 +3,12 @@
 class Outer {
   int x;
   static int sx;
+  int f();
 
-  // C++0x will likely relax this rule in this specific case, but
-  // we'll still need to enforce it in C++03 mode.  See N2253 (or
-  // successor).
+  // C++0x does relax this rule (see 5.1.1.10) in the first case, but we need to enforce it in C++03 mode.
   class Inner {
     static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }}
     static char b[sizeof(sx)]; // okay
+    static char c[sizeof(f)]; // expected-error {{ call to non-static member function without an object argument }}
   };
 };





More information about the cfe-commits mailing list