From: Richard Smith Date: Sat, 25 Feb 2012 10:04:07 +0000 (+0000) Subject: PR11956: C++11's special exception for accessing non-static data members from X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2c8aee454dac03e4918f0bb6e7fb849953056aba;p=clang 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 --- 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 +}