forked from OSchip/llvm-project
Do not mark declarations as used when performing overload resolution. Fixes PR5541
llvm-svn: 89652
This commit is contained in:
parent
65911498ef
commit
27381f3d93
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue