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
This commit is contained in:
Richard Smith 2012-02-25 10:04:07 +00:00
Родитель 7a9f49296a
Коммит 2c8aee454d
2 изменённых файлов: 24 добавлений и 16 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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));
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
}