diff options
author | Reid Kleckner <rnk@google.com> | 2015-10-20 00:31:42 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-10-20 00:31:42 +0000 |
commit | 7d3a2f067f856aff28e3dde7ec3749f69eb65f1c (patch) | |
tree | 4b9fe8afc2d968853121e19570ab9854eadff286 | |
parent | 3e7e915dca7dd543f11bdb6312e95a857df22618 (diff) | |
download | bcm5719-llvm-7d3a2f067f856aff28e3dde7ec3749f69eb65f1c.tar.gz bcm5719-llvm-7d3a2f067f856aff28e3dde7ec3749f69eb65f1c.zip |
Revert "Diagnose UnresolvedLookupExprs that resolve to instance members in static methods"
This reverts commit r250592.
It has issues around unevaluated contexts, like this:
template <class T> struct A { T i; };
template <class T>
struct B : A<T> {
using A<T>::i;
typedef decltype(i) U;
};
template struct B<int>;
llvm-svn: 250774
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 12 | ||||
-rw-r--r-- | clang/test/SemaCXX/using-decl-1.cpp | 51 |
4 files changed, 16 insertions, 75 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d0b3e627f69..cce5405a1e0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3692,9 +3692,6 @@ public: Expr *baseObjectExpr = nullptr, SourceLocation opLoc = SourceLocation()); - void DiagnoseInstanceReference(const CXXScopeSpec &SS, NamedDecl *Rep, - const DeclarationNameInfo &nameInfo); - ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 3256bd986ff..52dfceccb94 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -192,8 +192,10 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, } /// Diagnose a reference to a field with no object available. -void Sema::DiagnoseInstanceReference(const CXXScopeSpec &SS, NamedDecl *Rep, - const DeclarationNameInfo &nameInfo) { +static void diagnoseInstanceReference(Sema &SemaRef, + const CXXScopeSpec &SS, + NamedDecl *Rep, + const DeclarationNameInfo &nameInfo) { SourceLocation Loc = nameInfo.getLoc(); SourceRange Range(Loc); if (SS.isSet()) Range.setBegin(SS.getRange().getBegin()); @@ -201,7 +203,7 @@ void Sema::DiagnoseInstanceReference(const CXXScopeSpec &SS, NamedDecl *Rep, // Look through using shadow decls and aliases. Rep = Rep->getUnderlyingDecl(); - DeclContext *FunctionLevelDC = getFunctionLevelDeclContext(); + DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext(); CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC); CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr; CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext()); @@ -211,19 +213,20 @@ void Sema::DiagnoseInstanceReference(const CXXScopeSpec &SS, NamedDecl *Rep, if (IsField && InStaticMethod) // "invalid use of member 'x' in static member function" - Diag(Loc, diag::err_invalid_member_use_in_static_method) + SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method) << Range << nameInfo.getName(); else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod && !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass)) // Unqualified lookup in a non-static member function found a member of an // enclosing class. - Diag(Loc, diag::err_nested_non_static_member_use) - << IsField << RepClass << nameInfo.getName() << ContextClass << Range; + SemaRef.Diag(Loc, diag::err_nested_non_static_member_use) + << IsField << RepClass << nameInfo.getName() << ContextClass << Range; else if (IsField) - Diag(Loc, diag::err_invalid_non_static_member_use) << nameInfo.getName() - << Range; + SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use) + << nameInfo.getName() << Range; else - Diag(Loc, diag::err_member_call_without_object) << Range; + SemaRef.Diag(Loc, diag::err_member_call_without_object) + << Range; } /// Builds an expression which might be an implicit member expression. @@ -257,7 +260,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, case IMA_Error_StaticContext: case IMA_Error_Unrelated: - DiagnoseInstanceReference(SS, R.getRepresentativeDecl(), + diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(), R.getLookupNameInfo()); return ExprError(); } @@ -471,7 +474,7 @@ static void DiagnoseQualifiedMemberReference(Sema &SemaRef, // If this is an implicit member access, use a different set of // diagnostics. if (!BaseExpr) - return SemaRef.DiagnoseInstanceReference(SS, rep, nameInfo); + return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo); SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated) << SS.getRange() << rep << BaseType; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 81c56c2f2c6..31d69cbac35 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9128,18 +9128,8 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( // If we have neither explicit template arguments, nor the template keyword, // it's a normal declaration name. - if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) { - // If an UnresolvedLookupExpr resolved to an instance member, that's an - // error. - NamedDecl *D = R.getAsSingle<NamedDecl>(); - if (D && D->isCXXInstanceMember()) { - SemaRef.DiagnoseInstanceReference(SS, D, Old->getNameInfo()); - R.clear(); - return ExprError(); - } - + if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); - } // If we have template arguments, rebuild them, then rebuild the // templateid expression. diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp index ac53b3758e4..ca532692c1c 100644 --- a/clang/test/SemaCXX/using-decl-1.cpp +++ b/clang/test/SemaCXX/using-decl-1.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -// RUN: %clang_cc1 -DCXX11 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s extern "C" { void f(bool); } @@ -327,52 +327,3 @@ namespace PR24033 { using PR24033::st; // expected-error {{target of using declaration conflicts with declaration already in scope}} } } - -namespace pr21923 { -template <typename> struct Base { - int field; - void method(); -}; -template <typename Scalar> struct Derived : Base<Scalar> { - using Base<Scalar>::field; - using Base<Scalar>::method; - static void m_fn1() { - // expected-error@+1 {{invalid use of member 'field' in static member function}} - (void)field; - // expected-error@+1 {{invalid use of member 'field' in static member function}} - (void)&field; - // expected-error@+1 {{call to non-static member function without an object argument}} - (void)method; - // expected-error@+1 {{call to non-static member function without an object argument}} - (void)&method; - // expected-error@+1 {{call to non-static member function without an object argument}} - method(); - (void)&Base<Scalar>::field; - (void)&Base<Scalar>::method; - } -}; -// expected-note@+1 {{in instantiation of member function 'pr21923::Derived<int>::m_fn1' requested here}} -template class Derived<int>; - -#ifdef CXX11 -// This is interesting because we form an UnresolvedLookupExpr in the static -// function template and an UnresolvedMemberExpr in the instance function -// template. As a result, we get slightly different behavior. -struct UnresolvedTemplateNames { - template <typename> void maybe_static(); - template <typename T, typename T::type = 0> static void maybe_static(); - - template <typename T> - void instance_method() { (void)maybe_static<T>(); } - template <typename T> - static void static_method() { - // expected-error@+1 {{call to non-static member function without an object argument}} - (void)maybe_static<T>(); - } -}; -void force_instantiation(UnresolvedTemplateNames x) { - x.instance_method<int>(); - UnresolvedTemplateNames::static_method<int>(); // expected-note {{requested here}} -} -#endif // CXX11 -} |