Don't allow the same function to enter the overload candidate set
multiple times. This requires to be more careful about re-adding
candidates cached from the function template definition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82967 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 2acc4e4..8909d98 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2186,7 +2186,9 @@
// argument doesn't participate in overload resolution.
}
-
+ if (!CandidateSet.isNewCandidate(Function))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2256,14 +2258,29 @@
for (FunctionSet::const_iterator F = Functions.begin(),
FEnd = Functions.end();
F != FEnd; ++F) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F))
- AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
- SuppressUserConversions);
- else
- AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F),
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F)) {
+ if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
+ AddMethodCandidate(cast<CXXMethodDecl>(FD),
+ Args[0], Args + 1, NumArgs - 1,
+ CandidateSet, SuppressUserConversions);
+ else
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ } else {
+ FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*F);
+ if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
+ !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
+ AddMethodTemplateCandidate(FunTmpl,
/*FIXME: explicit args */false, 0, 0,
- Args, NumArgs, CandidateSet,
+ Args[0], Args + 1, NumArgs - 1,
+ CandidateSet,
SuppressUserConversions);
+ else
+ AddTemplateOverloadCandidate(FunTmpl,
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ }
}
}
@@ -2289,6 +2306,9 @@
assert(!isa<CXXConstructorDecl>(Method) &&
"Use AddOverloadCandidate for constructors");
+ if (!CandidateSet.isNewCandidate(Method))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2375,6 +2395,9 @@
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
bool ForceRValue) {
+ if (!CandidateSet.isNewCandidate(MethodTmpl))
+ return;
+
// C++ [over.match.funcs]p7:
// In each case where a candidate is a function template, candidate
// function template specializations are generated using template argument
@@ -2417,6 +2440,9 @@
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
bool ForceRValue) {
+ if (!CandidateSet.isNewCandidate(FunctionTemplate))
+ return;
+
// C++ [over.match.funcs]p7:
// In each case where a candidate is a function template, candidate
// function template specializations are generated using template argument
@@ -2458,6 +2484,9 @@
assert(!Conversion->getDescribedFunctionTemplate() &&
"Conversion function templates use AddTemplateConversionCandidate");
+ if (!CandidateSet.isNewCandidate(Conversion))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2538,6 +2567,9 @@
assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
"Only conversion function templates permitted here");
+ if (!CandidateSet.isNewCandidate(FunctionTemplate))
+ return;
+
TemplateDeductionInfo Info(Context);
CXXConversionDecl *Specialization = 0;
if (TemplateDeductionResult Result
@@ -2564,6 +2596,9 @@
const FunctionProtoType *Proto,
Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet) {
+ if (!CandidateSet.isNewCandidate(Conversion))
+ return;
+
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
Candidate.Function = 0;
@@ -2649,7 +2684,6 @@
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
SourceRange OpRange) {
-
FunctionSet Functions;
QualType T1 = Args[0]->getType();
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
index 17f5598..898393a 100644
--- a/lib/Sema/SemaOverload.h
+++ b/lib/Sema/SemaOverload.h
@@ -261,7 +261,16 @@
/// OverloadCandidateSet - A set of overload candidates, used in C++
/// overload resolution (C++ 13.3).
- typedef llvm::SmallVector<OverloadCandidate, 16> OverloadCandidateSet;
+ class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> {
+ llvm::SmallPtrSet<Decl *, 16> Functions;
+
+ public:
+ /// \brief Determine when this overload candidate will be new to the
+ /// overload set.
+ bool isNewCandidate(Decl *F) {
+ return Functions.insert(F->getCanonicalDecl());
+ }
+ };
} // end namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H