diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-12-18 00:42:51 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-12-18 00:42:51 +0000 |
commit | ae628965c4afb428a927b78acf66f056c254e99b (patch) | |
tree | aa0e69302e07871ac86e59574f8d8f4f0434ef29 | |
parent | 323ddf97bad613d5c732412fd08965c48bed85f4 (diff) | |
download | bcm5719-llvm-ae628965c4afb428a927b78acf66f056c254e99b.tar.gz bcm5719-llvm-ae628965c4afb428a927b78acf66f056c254e99b.zip |
Fix diagnostic for static methods referencing fields from using decls
Previously we thought the instance member was a function, not a field,
and we'd say something silly like:
t.cpp:4:27: error: call to non-static member function without an object argument
static int f() { return n; }
^
Noticed in PR21923.
llvm-svn: 224480
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/using-decl-1.cpp | 8 |
2 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 1f52cd87fae..f8a00cc6ef0 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -90,7 +90,6 @@ enum IMAKind { /// conservatively answer "yes", in which case some errors will simply /// not be caught until template-instantiation. static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, - Scope *CurScope, const LookupResult &R) { assert(!R.empty() && (*R.begin())->isCXXClassMember()); @@ -205,6 +204,9 @@ static void diagnoseInstanceReference(Sema &SemaRef, SourceRange Range(Loc); if (SS.isSet()) Range.setBegin(SS.getRange().getBegin()); + // Look through using shadow decls and aliases. + Rep = Rep->getUnderlyingDecl(); + DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext(); CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC); CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr; @@ -237,7 +239,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { - switch (ClassifyImplicitMemberAccess(*this, CurScope, R)) { + switch (ClassifyImplicitMemberAccess(*this, R)) { case IMA_Instance: return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true); diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp index 40f80a70ef3..e730c9d63a2 100644 --- a/clang/test/SemaCXX/using-decl-1.cpp +++ b/clang/test/SemaCXX/using-decl-1.cpp @@ -255,3 +255,11 @@ namespace TypoCorrectTemplateMember { using A::goobar; // expected-error {{no member named 'goobar' in 'TypoCorrectTemplateMember::A'; did you mean 'foobar'?}} }; } + +namespace use_instance_in_static { +struct A { int n; }; +struct B : A { + using A::n; + static int f() { return n; } // expected-error {{invalid use of member 'n' in static member function}} +}; +} |