Do not mark declarations as used when performing overload resolution. Fixes PR5541

llvm-svn: 89652
This commit is contained in:
Douglas Gregor 2009-11-23 12:27:39 +00:00
parent 65911498ef
commit 27381f3d93
4 changed files with 63 additions and 4 deletions

View File

@ -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));

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}