From 27381f3d93454ef46c7ede3089d910930e7ffabf Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 23 Nov 2009 12:27:39 +0000 Subject: [PATCH] Do not mark declarations as used when performing overload resolution. Fixes PR5541 llvm-svn: 89652 --- clang/lib/Sema/SemaDeclCXX.cpp | 2 + clang/lib/Sema/SemaExprCXX.cpp | 8 ++-- clang/lib/Sema/SemaOverload.cpp | 15 ++++++++ clang/test/SemaTemplate/overload-uneval.cpp | 42 +++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 clang/test/SemaTemplate/overload-uneval.cpp diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 5becd8b66237..3ff9144cc21c 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3291,6 +3291,7 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, unsigned NumExprs = ExprArgs.size(); Expr **Exprs = (Expr **)ExprArgs.release(); + MarkDeclarationReferenced(ConstructLoc, Constructor); return Owned(CXXConstructExpr::Create(Context, DeclInitType, Constructor, Elidable, Exprs, NumExprs)); } @@ -3304,6 +3305,7 @@ Sema::BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Constructor, unsigned NumExprs = Args.size(); Expr **Exprs = (Expr **)Args.release(); + MarkDeclarationReferenced(TyBeginLoc, Constructor); return Owned(new (Context) CXXTemporaryObjectExpr(Context, Constructor, Ty, TyBeginLoc, Exprs, NumExprs, RParenLoc)); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 790c849b93fc..24fd6c5eebb2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2201,10 +2201,10 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, else ResultType = Method->getResultType().getNonReferenceType(); - CXXMemberCallExpr *CE = - new (Context) CXXMemberCallExpr(Context, ME, 0, 0, - ResultType, - Exp->getLocEnd()); + MarkDeclarationReferenced(Exp->getLocStart(), Method); + CXXMemberCallExpr *CE = + new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, + Exp->getLocEnd()); return CE; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8a009e57f6de..7366ec978b4a 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2240,6 +2240,9 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, if (!CandidateSet.isNewCandidate(Function)) return; + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); + if (CXXConstructorDecl *Constructor = dyn_cast(Function)){ // C++ [class.copy]p3: // A member function template is never instantiated to perform the copy @@ -2416,6 +2419,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object, if (!CandidateSet.isNewCandidate(Method)) return; + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); + // Add this candidate CandidateSet.push_back(OverloadCandidate()); OverloadCandidate& Candidate = CandidateSet.back(); @@ -2588,6 +2594,9 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, if (!CandidateSet.isNewCandidate(Conversion)) return; + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); + // Add this candidate CandidateSet.push_back(OverloadCandidate()); OverloadCandidate& Candidate = CandidateSet.back(); @@ -2712,6 +2721,9 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, if (!CandidateSet.isNewCandidate(Conversion)) return; + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); + CandidateSet.push_back(OverloadCandidate()); OverloadCandidate& Candidate = CandidateSet.back(); Candidate.Function = 0; @@ -2877,6 +2889,9 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator, unsigned NumContextualBoolArguments) { + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated); + // Add this candidate CandidateSet.push_back(OverloadCandidate()); OverloadCandidate& Candidate = CandidateSet.back(); diff --git a/clang/test/SemaTemplate/overload-uneval.cpp b/clang/test/SemaTemplate/overload-uneval.cpp new file mode 100644 index 000000000000..2e3bfede700a --- /dev/null +++ b/clang/test/SemaTemplate/overload-uneval.cpp @@ -0,0 +1,42 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Tests that overload resolution is treated as an unevaluated context. +// PR5541 +struct Foo +{ + Foo *next; +}; + +template +struct Bar +{ +}; + + +template +class Wibble +{ + typedef Bar B; + + static inline B *concrete(Foo *node) { + int a[sizeof(T) ? -1 : -1]; + return reinterpret_cast(node); + } + +public: + class It + { + Foo *i; + + public: + inline operator B *() const { return concrete(i); } + inline bool operator!=(const It &o) const { return i != +o.i; } + }; +}; + +void f() { + Wibble::It a, b; + + a != b; +}