aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-23 12:27:39 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-23 12:27:39 +0000
commit7edfb69ae192d9c1f5b1f32af30130f34f98386e (patch)
treef4199e39fde91baf468aa42521660478abe53eca
parent3ebd75399112dd9ad1c96ee5e7c59df580378cc8 (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.cpp2
-rw-r--r--lib/Sema/SemaExprCXX.cpp8
-rw-r--r--lib/Sema/SemaOverload.cpp15
-rw-r--r--test/SemaTemplate/overload-uneval.cpp42
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;
+}