forked from OSchip/llvm-project
Allow access to non-static members without an object in sizeof expressions, in C++0x. Patch by Jakub Wieczorek.
llvm-svn: 120182
This commit is contained in:
parent
4fcd9163fc
commit
346203105f
|
@ -1038,11 +1038,15 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
|
||||||
|
|
||||||
// Collect all the declaring classes of instance members we find.
|
// Collect all the declaring classes of instance members we find.
|
||||||
bool hasNonInstance = false;
|
bool hasNonInstance = false;
|
||||||
|
bool hasField = false;
|
||||||
llvm::SmallPtrSet<CXXRecordDecl*, 4> Classes;
|
llvm::SmallPtrSet<CXXRecordDecl*, 4> Classes;
|
||||||
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
|
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
|
||||||
NamedDecl *D = *I;
|
NamedDecl *D = *I;
|
||||||
|
|
||||||
if (D->isCXXInstanceMember()) {
|
if (D->isCXXInstanceMember()) {
|
||||||
|
if (dyn_cast<FieldDecl>(D))
|
||||||
|
hasField = true;
|
||||||
|
|
||||||
CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
|
CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
|
||||||
Classes.insert(R->getCanonicalDecl());
|
Classes.insert(R->getCanonicalDecl());
|
||||||
}
|
}
|
||||||
|
@ -1057,8 +1061,24 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
|
||||||
|
|
||||||
// If the current context is not an instance method, it can't be
|
// If the current context is not an instance method, it can't be
|
||||||
// an implicit member reference.
|
// an implicit member reference.
|
||||||
if (isStaticContext)
|
if (isStaticContext) {
|
||||||
return (hasNonInstance ? IMA_Mixed_StaticContext : IMA_Error_StaticContext);
|
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
|
// If we can prove that the current context is unrelated to all the
|
||||||
// declaring classes, it can't be an implicit member reference (in
|
// declaring classes, it can't be an implicit member reference (in
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
class Outer {
|
class Outer {
|
||||||
int x;
|
int x;
|
||||||
static int sx;
|
static int sx;
|
||||||
|
int f();
|
||||||
|
|
||||||
// C++0x will likely relax this rule in this specific case, but
|
// 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.
|
||||||
// we'll still need to enforce it in C++03 mode. See N2253 (or
|
|
||||||
// successor).
|
|
||||||
class Inner {
|
class Inner {
|
||||||
static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }}
|
static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }}
|
||||||
static char b[sizeof(sx)]; // okay
|
static char b[sizeof(sx)]; // okay
|
||||||
|
static char c[sizeof(f)]; // expected-error {{ call to non-static member function without an object argument }}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue