aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-19 23:54:39 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-19 23:54:39 +0000
commitdfc331e04d4c6a09fb693a15fc5a57d29a198c86 (patch)
tree7e8d49934bb4f23d87a8cdefc282d2cb072edeb9
parent83d7781f9dc869022d48dbabde34dbfbd6f59a17 (diff)
Explicitly track the number of call arguments provided when performing
overload resolution, so that we only use that number of call arguments for partial ordering. Fixes PR9006, a recent regression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123861 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Overload.h4
-rw-r--r--lib/Sema/SemaOverload.cpp17
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp14
3 files changed, 31 insertions, 4 deletions
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 404d895756..56b0f53bc6 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -549,6 +549,10 @@ namespace clang {
/// Actually an OverloadFailureKind.
unsigned char FailureKind;
+ /// \brief The number of call arguments that were explicitly provided,
+ /// to be used while performing partial ordering of function templates.
+ unsigned ExplicitCallArguments;
+
/// A structure used to record information about a failed
/// template argument deduction.
struct DeductionFailureInfo {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index a1b09d91f2..0b401007b8 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3551,7 +3551,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
Candidate.Viable = true;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
-
+ Candidate.ExplicitCallArguments = NumArgs;
+
unsigned NumArgsInProto = Proto->getNumArgs();
// (C++ 13.3.2p2): A candidate function having fewer than m
@@ -3701,6 +3702,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
Candidate.Function = Method;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
+ Candidate.ExplicitCallArguments = NumArgs;
unsigned NumArgsInProto = Proto->getNumArgs();
@@ -3809,6 +3811,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
+ Candidate.ExplicitCallArguments = NumArgs;
Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
@@ -3859,6 +3862,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
+ Candidate.ExplicitCallArguments = NumArgs;
Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
@@ -3904,6 +3908,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Candidate.FinalConversion.setAllToTypes(ToType);
Candidate.Viable = true;
Candidate.Conversions.resize(1);
+ Candidate.ExplicitCallArguments = 1;
// C++ [over.match.funcs]p4:
// For conversion functions, the function is considered to be a member of
@@ -4032,6 +4037,7 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
+ Candidate.ExplicitCallArguments = 1;
Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
@@ -4071,6 +4077,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
Candidate.IsSurrogate = true;
Candidate.IgnoreObjectArgument = false;
Candidate.Conversions.resize(NumArgs + 1);
+ Candidate.ExplicitCallArguments = NumArgs;
// Determine the implicit conversion sequence for the implicit
// object parameter.
@@ -4222,6 +4229,7 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
// arguments.
Candidate.Viable = true;
Candidate.Conversions.resize(NumArgs);
+ Candidate.ExplicitCallArguments = NumArgs;
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
// C++ [over.match.oper]p4:
// For the built-in assignment operators, conversions of the
@@ -5891,16 +5899,17 @@ isBetterOverloadCandidate(Sema &S,
// according to the partial ordering rules described in 14.5.5.2, or,
// if not that,
if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
- Cand2.Function && Cand2.Function->getPrimaryTemplate())
+ Cand2.Function && Cand2.Function->getPrimaryTemplate()) {
if (FunctionTemplateDecl *BetterTemplate
= S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
Cand2.Function->getPrimaryTemplate(),
Loc,
isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
: TPOC_Call,
- NumArgs))
+ Cand1.ExplicitCallArguments))
return BetterTemplate == Cand1.Function->getPrimaryTemplate();
-
+ }
+
// -- the context is an initialization by user-defined conversion
// (see 8.5, 13.3.1.5) and the standard conversion sequence
// from the return type of F1 to the destination type (i.e.,
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
index 5aabebae94..01155e136a 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
@@ -31,3 +31,17 @@ void g3() {
f3<int>( 42 ); // expected-error{{call to 'f3' is ambiguous}}
}
+
+namespace PR9006 {
+ struct X {
+ template <class Get>
+ int &f(char const* name, Get fget, char const* docstr = 0);
+
+ template <class Get, class Set>
+ float &f(char const* name, Get fget, Set fset, char const* docstr = 0);
+ };
+
+ void test(X x) {
+ int &ir = x.f("blah", 0, "blah");
+ }
+}