diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-23 12:27:39 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-23 12:27:39 +0000 |
commit | 7edfb69ae192d9c1f5b1f32af30130f34f98386e (patch) | |
tree | f4199e39fde91baf468aa42521660478abe53eca | |
parent | 3ebd75399112dd9ad1c96ee5e7c59df580378cc8 (diff) |
Do not mark declarations as used when performing overload resolution. Fixes PR5541
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89652 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 15 | ||||
-rw-r--r-- | test/SemaTemplate/overload-uneval.cpp | 42 |
4 files changed, 63 insertions, 4 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 5becd8b662..3ff9144cc2 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/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/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 790c849b93..24fd6c5eeb 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/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/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 8a009e57f6..7366ec978b 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/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<CXXConstructorDecl>(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/test/SemaTemplate/overload-uneval.cpp b/test/SemaTemplate/overload-uneval.cpp new file mode 100644 index 0000000000..2e3bfede70 --- /dev/null +++ b/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 <typename> +struct Bar +{ +}; + + +template <typename T> +class Wibble +{ + typedef Bar<T> B; + + static inline B *concrete(Foo *node) { + int a[sizeof(T) ? -1 : -1]; + return reinterpret_cast<B *>(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<void*>::It a, b; + + a != b; +} |