aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-25 10:04:07 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-25 10:04:07 +0000
commit2c8aee454dac03e4918f0bb6e7fb849953056aba (patch)
tree744e2c883ae768d1d28ac61c0bbd3195b1df24cd
parent7a9f49296a6454b7a6f0edce89dc99d413a7e14e (diff)
PR11956: C++11's special exception for accessing non-static data members from
unevaluated operands applies within member functions, too. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151443 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExprMember.cpp30
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp10
2 files changed, 24 insertions, 16 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 54296942d0..e90d6e1bc9 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -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;
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
index 59c8660aa1..606300b1b2 100644
--- a/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
@@ -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
+}