summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@linaro.org>2017-01-02 11:15:42 +0000
committerRenato Golin <renato.golin@linaro.org>2017-01-02 11:15:42 +0000
commitdad96d67515af247a45c8ca1bd4ebb2b27746cac (patch)
tree512ee5bb82e385fd2cd47bbf72bcbd15815d3d1f /clang/lib
parent21706cbd248804520cb093ec17d296e48a89a65b (diff)
downloadbcm5719-llvm-dad96d67515af247a45c8ca1bd4ebb2b27746cac.tar.gz
bcm5719-llvm-dad96d67515af247a45c8ca1bd4ebb2b27746cac.zip
Revert "DR1391: Check for implicit conversion sequences for non-dependent function template parameters between deduction and substitution. The idea is to accept as many cases as possible, on the basis that substitution failure outside the immediate context is much more common during substitution than during implicit conversion sequence formation."
This reverts commit r290808, as it broken all ARM and AArch64 test-suite test: MultiSource/UnitTests/C++11/frame_layout Also, please, next time, try to write a commit message in according to our guidelines: http://llvm.org/docs/DeveloperPolicy.html#commit-messages llvm-svn: 290811
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp257
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp36
2 files changed, 85 insertions, 208 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a2ee2b00ecf..47e3df20d91 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -589,6 +589,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
Result.Result = static_cast<unsigned>(TDK);
Result.HasDiagnostic = false;
switch (TDK) {
+ case Sema::TDK_Success:
case Sema::TDK_Invalid:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_TooManyArguments:
@@ -647,10 +648,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
case Sema::TDK_FailedOverloadResolution:
Result.Data = Info.Expression;
break;
-
- case Sema::TDK_Success:
- case Sema::TDK_NonDependentConversionFailure:
- llvm_unreachable("not a deduction failure");
}
return Result;
@@ -667,7 +664,6 @@ void DeductionFailureInfo::Destroy() {
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_CUDATargetMismatch:
- case Sema::TDK_NonDependentConversionFailure:
break;
case Sema::TDK_Inconsistent:
@@ -711,7 +707,6 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_CUDATargetMismatch:
- case Sema::TDK_NonDependentConversionFailure:
return TemplateParameter();
case Sema::TDK_Incomplete:
@@ -744,7 +739,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_CUDATargetMismatch:
- case Sema::TDK_NonDependentConversionFailure:
return nullptr;
case Sema::TDK_DeducedMismatch:
@@ -773,7 +767,6 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_CUDATargetMismatch:
- case Sema::TDK_NonDependentConversionFailure:
return nullptr;
case Sema::TDK_Inconsistent:
@@ -802,7 +795,6 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_CUDATargetMismatch:
- case Sema::TDK_NonDependentConversionFailure:
return nullptr;
case Sema::TDK_Inconsistent:
@@ -837,8 +829,8 @@ llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() {
void OverloadCandidateSet::destroyCandidates() {
for (iterator i = begin(), e = end(); i != e; ++i) {
- for (auto &C : i->Conversions)
- C.~ImplicitConversionSequence();
+ for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii)
+ i->Conversions[ii].~ImplicitConversionSequence();
if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction)
i->DeductionFailure.Destroy();
}
@@ -5845,8 +5837,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
OverloadCandidateSet &CandidateSet,
bool SuppressUserConversions,
bool PartialOverloading,
- bool AllowExplicit,
- ConversionSequenceList EarlyConversions) {
+ bool AllowExplicit) {
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
assert(Proto && "Functions without a prototype cannot be overloaded");
@@ -5865,7 +5856,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
AddMethodCandidate(Method, FoundDecl, Method->getParent(),
QualType(), Expr::Classification::makeSimpleLValue(),
Args, CandidateSet, SuppressUserConversions,
- PartialOverloading, EarlyConversions);
+ PartialOverloading);
return;
}
// We treat a constructor like a non-member function, since its object
@@ -5898,8 +5889,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
- OverloadCandidate &Candidate =
- CandidateSet.addCandidate(Args.size(), EarlyConversions);
+ OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size());
Candidate.FoundDecl = FoundDecl;
Candidate.Function = Function;
Candidate.Viable = true;
@@ -5963,10 +5953,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// Determine the implicit conversion sequences for each of the
// arguments.
for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
- if (Candidate.Conversions[ArgIdx].isInitialized()) {
- // We already formed a conversion sequence for this parameter during
- // template argument deduction.
- } else if (ArgIdx < NumParams) {
+ if (ArgIdx < NumParams) {
// (C++ 13.3.2p3): for F to be a viable function, there shall
// exist for each argument an implicit conversion sequence
// (13.3.3.1) that converts that argument to the corresponding
@@ -6275,8 +6262,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
bool SuppressUserConversions,
- bool PartialOverloading,
- ConversionSequenceList EarlyConversions) {
+ bool PartialOverloading) {
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
assert(Proto && "Methods without a prototype cannot be overloaded");
@@ -6297,8 +6283,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
- OverloadCandidate &Candidate =
- CandidateSet.addCandidate(Args.size() + 1, EarlyConversions);
+ OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1);
Candidate.FoundDecl = FoundDecl;
Candidate.Function = Method;
Candidate.IsSurrogate = false;
@@ -6360,10 +6345,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
// Determine the implicit conversion sequences for each of the
// arguments.
for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
- if (Candidate.Conversions[ArgIdx + 1].isInitialized()) {
- // We already formed a conversion sequence for this parameter during
- // template argument deduction.
- } else if (ArgIdx < NumParams) {
+ if (ArgIdx < NumParams) {
// (C++ 13.3.2p3): for F to be a viable function, there shall
// exist for each argument an implicit conversion sequence
// (13.3.3.1) that converts that argument to the corresponding
@@ -6424,30 +6406,19 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
// functions.
TemplateDeductionInfo Info(CandidateSet.getLocation());
FunctionDecl *Specialization = nullptr;
- ConversionSequenceList Conversions;
- if (TemplateDeductionResult Result = DeduceTemplateArguments(
- MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info,
- PartialOverloading, [&]() {
- return CheckNonDependentConversions(
- MethodTmpl, Args, CandidateSet, Conversions,
- SuppressUserConversions, ActingContext, ObjectType,
- ObjectClassification);
- })) {
- OverloadCandidate &Candidate =
- CandidateSet.addCandidate(Conversions.size(), Conversions);
+ if (TemplateDeductionResult Result
+ = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args,
+ Specialization, Info, PartialOverloading)) {
+ OverloadCandidate &Candidate = CandidateSet.addCandidate();
Candidate.FoundDecl = FoundDecl;
Candidate.Function = MethodTmpl->getTemplatedDecl();
Candidate.Viable = false;
+ Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = Args.size();
- if (Result == TDK_NonDependentConversionFailure)
- Candidate.FailureKind = ovl_fail_bad_conversion;
- else {
- Candidate.FailureKind = ovl_fail_bad_deduction;
- Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
- Info);
- }
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+ Info);
return;
}
@@ -6458,8 +6429,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
"Specialization is not a member function?");
AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
ActingContext, ObjectType, ObjectClassification, Args,
- CandidateSet, SuppressUserConversions, PartialOverloading,
- Conversions);
+ CandidateSet, SuppressUserConversions, PartialOverloading);
}
/// \brief Add a C++ function template specialization as a candidate
@@ -6487,29 +6457,19 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
// functions.
TemplateDeductionInfo Info(CandidateSet.getLocation());
FunctionDecl *Specialization = nullptr;
- ConversionSequenceList Conversions;
- if (TemplateDeductionResult Result = DeduceTemplateArguments(
- FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info,
- PartialOverloading, [&]() {
- return CheckNonDependentConversions(FunctionTemplate, Args,
- CandidateSet, Conversions,
- SuppressUserConversions);
- })) {
- OverloadCandidate &Candidate =
- CandidateSet.addCandidate(Conversions.size(), Conversions);
+ if (TemplateDeductionResult Result
+ = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args,
+ Specialization, Info, PartialOverloading)) {
+ OverloadCandidate &Candidate = CandidateSet.addCandidate();
Candidate.FoundDecl = FoundDecl;
Candidate.Function = FunctionTemplate->getTemplatedDecl();
Candidate.Viable = false;
+ Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = Args.size();
- if (Result == TDK_NonDependentConversionFailure)
- Candidate.FailureKind = ovl_fail_bad_conversion;
- else {
- Candidate.FailureKind = ovl_fail_bad_deduction;
- Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
- Info);
- }
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+ Info);
return;
}
@@ -6517,64 +6477,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
// deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet,
- SuppressUserConversions, PartialOverloading,
- /*AllowExplicit*/false, Conversions);
-}
-
-/// Check that implicit conversion sequences can be formed for each argument
-/// whose corresponding parameter has a non-dependent type, per DR1391's
-/// [temp.deduct.call]p10.
-bool Sema::CheckNonDependentConversions(
- FunctionTemplateDecl *FunctionTemplate, ArrayRef<Expr *> Args,
- OverloadCandidateSet &CandidateSet, ConversionSequenceList &Conversions,
- bool SuppressUserConversions, CXXRecordDecl *ActingContext,
- QualType ObjectType, Expr::Classification ObjectClassification) {
- // FIXME: The cases in which we allow explicit conversions for constructor
- // arguments never consider calling a constructor template. It's not clear
- // that is correct.
- const bool AllowExplicit = false;
-
- auto *FD = FunctionTemplate->getTemplatedDecl();
- auto *Method = dyn_cast<CXXMethodDecl>(FD);
- bool HasThisConversion = Method && !isa<CXXConstructorDecl>(Method);
- unsigned ThisConversions = HasThisConversion ? 1 : 0;
-
- Conversions =
- CandidateSet.allocateConversionSequences(ThisConversions + Args.size());
-
- // Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
-
- // For a method call, check the 'this' conversion here too. DR1391 doesn't
- // require that, but this check should never result in a hard error, and
- // overload resolution is permitted to sidestep instantiations.
- if (HasThisConversion && !cast<CXXMethodDecl>(FD)->isStatic() &&
- !ObjectType.isNull()) {
- Conversions[0] = TryObjectArgumentInitialization(
- *this, CandidateSet.getLocation(), ObjectType, ObjectClassification,
- Method, ActingContext);
- if (Conversions[0].isBad())
- return true;
- }
-
-
- for (unsigned I = 0, N = std::min<unsigned>(FD->getNumParams(), Args.size());
- I != N; ++I) {
- QualType ParamType = FD->getParamDecl(I)->getType();
- if (!ParamType->isDependentType()) {
- Conversions[ThisConversions + I]
- = TryCopyInitialization(*this, Args[I], ParamType,
- SuppressUserConversions,
- /*InOverloadResolution=*/true,
- /*AllowObjCWritebackConversion=*/
- getLangOpts().ObjCAutoRefCount,
- AllowExplicit);
- if (Conversions[ThisConversions + I].isBad())
- return true;
- }
- }
-
- return false;
+ SuppressUserConversions, PartialOverloading);
}
/// Determine whether this is an allowable conversion from the result
@@ -8813,8 +8716,8 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,
// Define functions that don't require ill-formed conversions for a given
// argument to be better candidates than functions that do.
- unsigned NumArgs = Cand1.Conversions.size();
- assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
+ unsigned NumArgs = Cand1.NumConversions;
+ assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch");
bool HasBetterConversion = false;
for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]);
@@ -10021,7 +9924,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
case ovl_fail_bad_conversion: {
unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0);
- for (unsigned N = Cand->Conversions.size(); I != N; ++I)
+ for (unsigned N = Cand->NumConversions; I != N; ++I)
if (Cand->Conversions[I].isBad())
return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress);
@@ -10084,12 +9987,12 @@ static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,
SourceLocation OpLoc,
OverloadCandidate *Cand) {
- assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary");
+ assert(Cand->NumConversions <= 2 && "builtin operator is not binary");
std::string TypeStr("operator");
TypeStr += Opc;
TypeStr += "(";
TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString();
- if (Cand->Conversions.size() == 1) {
+ if (Cand->NumConversions == 1) {
TypeStr += ")";
S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr;
} else {
@@ -10102,7 +10005,9 @@ static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,
static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
OverloadCandidate *Cand) {
- for (const ImplicitConversionSequence &ICS : Cand->Conversions) {
+ unsigned NoOperands = Cand->NumConversions;
+ for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
+ const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
if (ICS.isBad()) break; // all meaningless after first invalid
if (!ICS.isAmbiguous()) continue;
@@ -10122,8 +10027,7 @@ static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {
switch ((Sema::TemplateDeductionResult)DFI.Result) {
case Sema::TDK_Success:
- case Sema::TDK_NonDependentConversionFailure:
- llvm_unreachable("non-deduction failure while diagnosing bad deduction");
+ llvm_unreachable("TDK_success while diagnosing bad deduction");
case Sema::TDK_Invalid:
case Sema::TDK_Incomplete:
@@ -10226,11 +10130,11 @@ struct CompareOverloadCandidatesForDisplay {
// If there's any ordering between the defined conversions...
// FIXME: this might not be transitive.
- assert(L->Conversions.size() == R->Conversions.size());
+ assert(L->NumConversions == R->NumConversions);
int leftBetter = 0;
unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
- for (unsigned E = L->Conversions.size(); I != E; ++I) {
+ for (unsigned E = L->NumConversions; I != E; ++I) {
switch (CompareImplicitConversionSequences(S, Loc,
L->Conversions[I],
R->Conversions[I])) {
@@ -10279,8 +10183,7 @@ struct CompareOverloadCandidatesForDisplay {
}
/// CompleteNonViableCandidate - Normally, overload resolution only
-/// computes up to the first bad conversion. Produces the FixIt set if
-/// possible.
+/// computes up to the first. Produces the FixIt set if possible.
static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
ArrayRef<Expr *> Args) {
assert(!Cand->Viable);
@@ -10293,24 +10196,30 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
// Use a implicit copy initialization to check conversion fixes.
Cand->Fix.setConversionChecker(TryCopyInitialization);
- // Attempt to fix the bad conversion.
- unsigned ConvCount = Cand->Conversions.size();
- for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/;
- ++ConvIdx) {
+ // Skip forward to the first bad conversion.
+ unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
+ unsigned ConvCount = Cand->NumConversions;
+ while (true) {
assert(ConvIdx != ConvCount && "no bad conversion in candidate");
- if (Cand->Conversions[ConvIdx].isInitialized() &&
- Cand->Conversions[ConvIdx].isBad()) {
- Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
+ ConvIdx++;
+ if (Cand->Conversions[ConvIdx - 1].isBad()) {
+ Unfixable = !Cand->TryToFixBadConversion(ConvIdx - 1, S);
break;
}
}
+ if (ConvIdx == ConvCount)
+ return;
+
+ assert(!Cand->Conversions[ConvIdx].isInitialized() &&
+ "remaining conversion is initialized?");
+
// FIXME: this should probably be preserved from the overload
// operation somehow.
bool SuppressUserConversions = false;
- const FunctionProtoType *Proto;
- unsigned ArgIdx = 0;
+ const FunctionProtoType* Proto;
+ unsigned ArgIdx = ConvIdx;
if (Cand->IsSurrogate) {
QualType ConvType
@@ -10318,56 +10227,40 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
ConvType = ConvPtrType->getPointeeType();
Proto = ConvType->getAs<FunctionProtoType>();
- ArgIdx = 1;
+ ArgIdx--;
} else if (Cand->Function) {
Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
if (isa<CXXMethodDecl>(Cand->Function) &&
!isa<CXXConstructorDecl>(Cand->Function))
- ArgIdx = 1;
+ ArgIdx--;
} else {
// Builtin binary operator with a bad first conversion.
assert(ConvCount <= 3);
- for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
- ConvIdx != ConvCount; ++ConvIdx) {
- if (Cand->Conversions[ConvIdx].isInitialized())
- continue;
- if (Cand->BuiltinTypes.ParamTypes[ConvIdx]->isDependentType())
- Cand->Conversions[ConvIdx].setAsIdentityConversion(
- Args[ConvIdx]->getType());
- else
- Cand->Conversions[ConvIdx] = TryCopyInitialization(
- S, Args[ConvIdx], Cand->BuiltinTypes.ParamTypes[ConvIdx],
- SuppressUserConversions,
- /*InOverloadResolution*/ true,
- /*AllowObjCWritebackConversion=*/
- S.getLangOpts().ObjCAutoRefCount);
- // FIXME: If the conversion is bad, try to fix it.
- }
+ for (; ConvIdx != ConvCount; ++ConvIdx)
+ Cand->Conversions[ConvIdx]
+ = TryCopyInitialization(S, Args[ConvIdx],
+ Cand->BuiltinTypes.ParamTypes[ConvIdx],
+ SuppressUserConversions,
+ /*InOverloadResolution*/ true,
+ /*AllowObjCWritebackConversion=*/
+ S.getLangOpts().ObjCAutoRefCount);
return;
}
// Fill in the rest of the conversions.
unsigned NumParams = Proto->getNumParams();
- for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
- ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
- if (Cand->Conversions[ConvIdx].isInitialized()) {
- // Found the bad conversion.
- } else if (ArgIdx < NumParams) {
- if (Proto->getParamType(ArgIdx)->isDependentType())
- Cand->Conversions[ConvIdx].setAsIdentityConversion(
- Args[ArgIdx]->getType());
- else {
- Cand->Conversions[ConvIdx] =
- TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx),
- SuppressUserConversions,
- /*InOverloadResolution=*/true,
- /*AllowObjCWritebackConversion=*/
- S.getLangOpts().ObjCAutoRefCount);
- // Store the FixIt in the candidate if it exists.
- if (!Unfixable && Cand->Conversions[ConvIdx].isBad())
- Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
- }
- } else
+ for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
+ if (ArgIdx < NumParams) {
+ Cand->Conversions[ConvIdx] = TryCopyInitialization(
+ S, Args[ArgIdx], Proto->getParamType(ArgIdx), SuppressUserConversions,
+ /*InOverloadResolution=*/true,
+ /*AllowObjCWritebackConversion=*/
+ S.getLangOpts().ObjCAutoRefCount);
+ // Store the FixIt in the candidate if it exists.
+ if (!Unfixable && Cand->Conversions[ConvIdx].isBad())
+ Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
+ }
+ else
Cand->Conversions[ConvIdx].setEllipsis();
}
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index dc291836fb9..0bc85a2f263 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2849,13 +2849,14 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg,
///
/// \param OriginalCallArgs If non-NULL, the original call arguments against
/// which the deduced argument types should be compared.
-Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
- FunctionTemplateDecl *FunctionTemplate,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
- bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) {
+Sema::TemplateDeductionResult
+Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ unsigned NumExplicitlySpecified,
+ FunctionDecl *&Specialization,
+ TemplateDeductionInfo &Info,
+ SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
+ bool PartialOverloading) {
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
@@ -2882,18 +2883,6 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
PartialOverloading))
return Result;
- // C++ [temp.deduct.call]p10: [DR1391]
- // If deduction succeeds for all parameters that contain
- // template-parameters that participate in template argument deduction,
- // and all template arguments are explicitly specified, deduced, or
- // obtained from default template arguments, remaining parameters are then
- // compared with the corresponding arguments. For each remaining parameter
- // P with a type that was non-dependent before substitution of any
- // explicitly-specified template arguments, if the corresponding argument
- // A cannot be implicitly converted to P, deduction fails.
- if (CheckNonDependent())
- return TDK_NonDependentConversionFailure;
-
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
= TemplateArgumentList::CreateCopy(Context, Builder);
@@ -3318,17 +3307,12 @@ DeduceTemplateArgumentByListElement(Sema &S,
/// \param Info the argument will be updated to provide additional information
/// about template argument deduction.
///
-/// \param CheckNonDependent A callback to invoke to check conversions for
-/// non-dependent parameters, between deduction and substitution, per DR1391.
-/// If this returns true, substitution will be skipped and we return
-/// TDK_NonDependentConversionFailure.
-///
/// \returns the result of template argument deduction.
Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
FunctionDecl *&Specialization, TemplateDeductionInfo &Info,
- bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) {
+ bool PartialOverloading) {
if (FunctionTemplate->isInvalidDecl())
return TDK_Invalid;
@@ -3512,7 +3496,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
NumExplicitlySpecified, Specialization,
Info, &OriginalCallArgs,
- PartialOverloading, CheckNonDependent);
+ PartialOverloading);
}
QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
OpenPOWER on IntegriCloud