diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 261 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 61 | 
2 files changed, 227 insertions, 95 deletions
| diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c0321d36a7c..41f4fa746fc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -590,7 +590,6 @@ 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: @@ -646,6 +645,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,        Result.HasDiagnostic = true;      }      break; + +  case Sema::TDK_Success: +  case Sema::TDK_NonDependentConversionFailure: +    llvm_unreachable("not a deduction failure");    }    return Result; @@ -661,6 +664,7 @@ void DeductionFailureInfo::Destroy() {    case Sema::TDK_TooFewArguments:    case Sema::TDK_InvalidExplicitArguments:    case Sema::TDK_CUDATargetMismatch: +  case Sema::TDK_NonDependentConversionFailure:      break;    case Sema::TDK_Inconsistent: @@ -705,6 +709,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {    case Sema::TDK_DeducedMismatchNested:    case Sema::TDK_NonDeducedMismatch:    case Sema::TDK_CUDATargetMismatch: +  case Sema::TDK_NonDependentConversionFailure:      return TemplateParameter();    case Sema::TDK_Incomplete: @@ -736,6 +741,7 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {    case Sema::TDK_Underqualified:    case Sema::TDK_NonDeducedMismatch:    case Sema::TDK_CUDATargetMismatch: +  case Sema::TDK_NonDependentConversionFailure:      return nullptr;    case Sema::TDK_DeducedMismatch: @@ -764,6 +770,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {    case Sema::TDK_InvalidExplicitArguments:    case Sema::TDK_SubstitutionFailure:    case Sema::TDK_CUDATargetMismatch: +  case Sema::TDK_NonDependentConversionFailure:      return nullptr;    case Sema::TDK_Inconsistent: @@ -792,6 +799,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {    case Sema::TDK_InvalidExplicitArguments:    case Sema::TDK_SubstitutionFailure:    case Sema::TDK_CUDATargetMismatch: +  case Sema::TDK_NonDependentConversionFailure:      return nullptr;    case Sema::TDK_Inconsistent: @@ -822,8 +830,8 @@ llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() {  void OverloadCandidateSet::destroyCandidates() {    for (iterator i = begin(), e = end(); i != e; ++i) { -    for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) -      i->Conversions[ii].~ImplicitConversionSequence(); +    for (auto &C : i->Conversions) +      C.~ImplicitConversionSequence();      if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction)        i->DeductionFailure.Destroy();    } @@ -5860,7 +5868,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,                             OverloadCandidateSet &CandidateSet,                             bool SuppressUserConversions,                             bool PartialOverloading, -                           bool AllowExplicit) { +                           bool AllowExplicit, +                           ConversionSequenceList EarlyConversions) {    const FunctionProtoType *Proto      = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());    assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -5876,10 +5885,11 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,        // function, e.g., X::f(). We use an empty type for the implied        // object argument (C++ [over.call.func]p3), and the acting context        // is irrelevant. -      AddMethodCandidate(Method, FoundDecl, Method->getParent(), -                         QualType(), Expr::Classification::makeSimpleLValue(), +      AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), +                         Expr::Classification::makeSimpleLValue(),                           /*ThisArg=*/nullptr, Args, CandidateSet, -                         SuppressUserConversions, PartialOverloading); +                         SuppressUserConversions, PartialOverloading, +                         EarlyConversions);        return;      }      // We treat a constructor like a non-member function, since its object @@ -5912,7 +5922,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,    EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);    // Add this candidate -  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); +  OverloadCandidate &Candidate = +      CandidateSet.addCandidate(Args.size(), EarlyConversions);    Candidate.FoundDecl = FoundDecl;    Candidate.Function = Function;    Candidate.Viable = true; @@ -5976,7 +5987,10 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,    // Determine the implicit conversion sequences for each of the    // arguments.    for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { -    if (ArgIdx < NumParams) { +    if (Candidate.Conversions[ArgIdx].isInitialized()) { +      // We already formed a conversion sequence for this parameter during +      // template argument deduction. +    } else 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 @@ -6414,7 +6428,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,                           Expr *ThisArg, ArrayRef<Expr *> Args,                           OverloadCandidateSet &CandidateSet,                           bool SuppressUserConversions, -                         bool PartialOverloading) { +                         bool PartialOverloading, +                         ConversionSequenceList EarlyConversions) {    const FunctionProtoType *Proto      = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());    assert(Proto && "Methods without a prototype cannot be overloaded"); @@ -6435,7 +6450,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,    EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);    // Add this candidate -  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1); +  OverloadCandidate &Candidate = +      CandidateSet.addCandidate(Args.size() + 1, EarlyConversions);    Candidate.FoundDecl = FoundDecl;    Candidate.Function = Method;    Candidate.IsSurrogate = false; @@ -6497,7 +6513,10 @@ 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 (ArgIdx < NumParams) { +    if (Candidate.Conversions[ArgIdx + 1].isInitialized()) { +      // We already formed a conversion sequence for this parameter during +      // template argument deduction. +    } else 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 @@ -6562,19 +6581,30 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,    //   functions.    TemplateDeductionInfo Info(CandidateSet.getLocation());    FunctionDecl *Specialization = nullptr; -  if (TemplateDeductionResult Result -      = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args, -                                Specialization, Info, PartialOverloading)) { -    OverloadCandidate &Candidate = CandidateSet.addCandidate(); +  ConversionSequenceList Conversions; +  if (TemplateDeductionResult Result = DeduceTemplateArguments( +          MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, +          PartialOverloading, [&](ArrayRef<QualType> ParamTypes) { +            return CheckNonDependentConversions( +                MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, +                SuppressUserConversions, ActingContext, ObjectType, +                ObjectClassification); +          })) { +    OverloadCandidate &Candidate = +        CandidateSet.addCandidate(Conversions.size(), Conversions);      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(); -    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, -                                                          Info); +    if (Result == TDK_NonDependentConversionFailure) +      Candidate.FailureKind = ovl_fail_bad_conversion; +    else { +      Candidate.FailureKind = ovl_fail_bad_deduction; +      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, +                                                            Info); +    }      return;    } @@ -6586,7 +6616,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,    AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,                       ActingContext, ObjectType, ObjectClassification,                       /*ThisArg=*/ThisArg, Args, CandidateSet, -                     SuppressUserConversions, PartialOverloading); +                     SuppressUserConversions, PartialOverloading, Conversions);  }  /// \brief Add a C++ function template specialization as a candidate @@ -6614,19 +6644,29 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,    //   functions.    TemplateDeductionInfo Info(CandidateSet.getLocation());    FunctionDecl *Specialization = nullptr; -  if (TemplateDeductionResult Result -        = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args, -                                  Specialization, Info, PartialOverloading)) { -    OverloadCandidate &Candidate = CandidateSet.addCandidate(); +  ConversionSequenceList Conversions; +  if (TemplateDeductionResult Result = DeduceTemplateArguments( +          FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info, +          PartialOverloading, [&](ArrayRef<QualType> ParamTypes) { +            return CheckNonDependentConversions(FunctionTemplate, ParamTypes, +                                                Args, CandidateSet, Conversions, +                                                SuppressUserConversions); +          })) { +    OverloadCandidate &Candidate = +        CandidateSet.addCandidate(Conversions.size(), Conversions);      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(); -    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, -                                                          Info); +    if (Result == TDK_NonDependentConversionFailure) +      Candidate.FailureKind = ovl_fail_bad_conversion; +    else { +      Candidate.FailureKind = ovl_fail_bad_deduction; +      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, +                                                            Info); +    }      return;    } @@ -6634,7 +6674,64 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,    // deduction as a candidate.    assert(Specialization && "Missing function template specialization?");    AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet, -                       SuppressUserConversions, PartialOverloading); +                       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<QualType> ParamTypes, +    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(ParamTypes.size(), Args.size()); I != N; +       ++I) { +    QualType ParamType = ParamTypes[I]; +    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;  }  /// Determine whether this is an allowable conversion from the result @@ -8875,8 +8972,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.NumConversions; -  assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch"); +  unsigned NumArgs = Cand1.Conversions.size(); +  assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");    bool HasBetterConversion = false;    for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {      bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]); @@ -10099,7 +10196,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,    case ovl_fail_bad_conversion: {      unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); -    for (unsigned N = Cand->NumConversions; I != N; ++I) +    for (unsigned N = Cand->Conversions.size(); I != N; ++I)        if (Cand->Conversions[I].isBad())          return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress); @@ -10168,12 +10265,12 @@ static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {  static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,                                           SourceLocation OpLoc,                                           OverloadCandidate *Cand) { -  assert(Cand->NumConversions <= 2 && "builtin operator is not binary"); +  assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary");    std::string TypeStr("operator");    TypeStr += Opc;    TypeStr += "(";    TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString(); -  if (Cand->NumConversions == 1) { +  if (Cand->Conversions.size() == 1) {      TypeStr += ")";      S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr;    } else { @@ -10186,9 +10283,7 @@ static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,  static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,                                           OverloadCandidate *Cand) { -  unsigned NoOperands = Cand->NumConversions; -  for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) { -    const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx]; +  for (const ImplicitConversionSequence &ICS : Cand->Conversions) {      if (ICS.isBad()) break; // all meaningless after first invalid      if (!ICS.isAmbiguous()) continue; @@ -10208,7 +10303,8 @@ static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {  static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {    switch ((Sema::TemplateDeductionResult)DFI.Result) {    case Sema::TDK_Success: -    llvm_unreachable("TDK_success while diagnosing bad deduction"); +  case Sema::TDK_NonDependentConversionFailure: +    llvm_unreachable("non-deduction failure while diagnosing bad deduction");    case Sema::TDK_Invalid:    case Sema::TDK_Incomplete: @@ -10311,11 +10407,11 @@ struct CompareOverloadCandidatesForDisplay {          // If there's any ordering between the defined conversions...          // FIXME: this might not be transitive. -        assert(L->NumConversions == R->NumConversions); +        assert(L->Conversions.size() == R->Conversions.size());          int leftBetter = 0;          unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); -        for (unsigned E = L->NumConversions; I != E; ++I) { +        for (unsigned E = L->Conversions.size(); I != E; ++I) {            switch (CompareImplicitConversionSequences(S, Loc,                                                       L->Conversions[I],                                                       R->Conversions[I])) { @@ -10364,7 +10460,8 @@ struct CompareOverloadCandidatesForDisplay {  }  /// CompleteNonViableCandidate - Normally, overload resolution only -/// computes up to the first. Produces the FixIt set if possible. +/// computes up to the first bad conversion. Produces the FixIt set if +/// possible.  static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,                                         ArrayRef<Expr *> Args) {    assert(!Cand->Viable); @@ -10377,30 +10474,24 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,    // Use a implicit copy initialization to check conversion fixes.    Cand->Fix.setConversionChecker(TryCopyInitialization); -  // Skip forward to the first bad conversion. -  unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); -  unsigned ConvCount = Cand->NumConversions; -  while (true) { +  // Attempt to fix the bad conversion. +  unsigned ConvCount = Cand->Conversions.size(); +  for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/; +       ++ConvIdx) {      assert(ConvIdx != ConvCount && "no bad conversion in candidate"); -    ConvIdx++; -    if (Cand->Conversions[ConvIdx - 1].isBad()) { -      Unfixable = !Cand->TryToFixBadConversion(ConvIdx - 1, S); +    if (Cand->Conversions[ConvIdx].isInitialized() && +        Cand->Conversions[ConvIdx].isBad()) { +      Unfixable = !Cand->TryToFixBadConversion(ConvIdx, 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 = ConvIdx; +  const FunctionProtoType *Proto; +  unsigned ArgIdx = 0;    if (Cand->IsSurrogate) {      QualType ConvType @@ -10408,40 +10499,56 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,      if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())        ConvType = ConvPtrType->getPointeeType();      Proto = ConvType->getAs<FunctionProtoType>(); -    ArgIdx--; +    ArgIdx = 1;    } else if (Cand->Function) {      Proto = Cand->Function->getType()->getAs<FunctionProtoType>();      if (isa<CXXMethodDecl>(Cand->Function) &&          !isa<CXXConstructorDecl>(Cand->Function)) -      ArgIdx--; +      ArgIdx = 1;    } else {      // Builtin binary operator with a bad first conversion.      assert(ConvCount <= 3); -    for (; ConvIdx != ConvCount; ++ConvIdx) -      Cand->Conversions[ConvIdx] -        = TryCopyInitialization(S, Args[ConvIdx], -                                Cand->BuiltinTypes.ParamTypes[ConvIdx], -                                SuppressUserConversions, -                                /*InOverloadResolution*/ true, -                                /*AllowObjCWritebackConversion=*/ -                                  S.getLangOpts().ObjCAutoRefCount); +    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. +    }      return;    }    // Fill in the rest of the conversions.    unsigned NumParams = Proto->getNumParams(); -  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 +  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        Cand->Conversions[ConvIdx].setEllipsis();    }  } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index a9fd8fd40ce..93e796ee966 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2912,14 +2912,13 @@ static unsigned getPackIndexForParam(Sema &S,  ///  /// \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) { +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) {    // Unevaluated SFINAE context.    EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);    SFINAETrap Trap(*this); @@ -2946,6 +2945,18 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,            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); @@ -3392,12 +3403,19 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(  /// \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. The callback is passed the parameter +/// types (after substituting explicit template arguments). +///  /// \returns the result of template argument deduction.  Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(      FunctionTemplateDecl *FunctionTemplate,      TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,      FunctionDecl *&Specialization, TemplateDeductionInfo &Info, -    bool PartialOverloading) { +    bool PartialOverloading, +    llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) {    if (FunctionTemplate->isInvalidDecl())      return TDK_Invalid; @@ -3425,7 +3443,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(    TemplateParameterList *TemplateParams      = FunctionTemplate->getTemplateParameters();    SmallVector<DeducedTemplateArgument, 4> Deduced; -  SmallVector<QualType, 4> ParamTypes; +  SmallVector<QualType, 8> ParamTypes;    unsigned NumExplicitlySpecified = 0;    if (ExplicitTemplateArgs) {      TemplateDeductionResult Result = @@ -3445,7 +3463,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(        ParamTypes.push_back(Function->getParamDecl(I)->getType());    } -  SmallVector<OriginalCallArg, 4> OriginalCallArgs; +  SmallVector<OriginalCallArg, 8> OriginalCallArgs;    // Deduce an argument of type ParamType from an expression with index ArgIdx.    auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx) { @@ -3464,6 +3482,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(    // Deduce template arguments from the function parameters.    Deduced.resize(TemplateParams->size()); +  SmallVector<QualType, 8> ParamTypesForArgChecking;    for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;         ParamIdx != NumParamTypes; ++ParamIdx) {      QualType ParamType = ParamTypes[ParamIdx]; @@ -3475,6 +3494,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(        if (ArgIdx >= Args.size())          break; +      ParamTypesForArgChecking.push_back(ParamType);        if (auto Result = DeduceCallArgument(ParamType, ArgIdx++))          return Result; @@ -3502,20 +3522,25 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(      // parameter pack and 0 otherwise, and we treat each deduction as a      // non-deduced context.      if (ParamIdx + 1 == NumParamTypes) { -      for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) +      for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) { +        ParamTypesForArgChecking.push_back(ParamPattern);          if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx))            return Result; +      }      } else {        // If the parameter type contains an explicitly-specified pack that we        // could not expand, skip the number of parameters notionally created        // by the expansion.        Optional<unsigned> NumExpansions = ParamExpansion->getNumExpansions(); -      if (NumExpansions && !PackScope.isPartiallyExpanded()) +      if (NumExpansions && !PackScope.isPartiallyExpanded()) {          for (unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size(); -             ++I, ++ArgIdx) +             ++I, ++ArgIdx) { +          ParamTypesForArgChecking.push_back(ParamPattern);            // FIXME: Should we add OriginalCallArgs for these? What if the            // corresponding argument is a list?            PackScope.nextPackElement(); +        } +      }      }      // Build argument packs for each of the parameter packs expanded by this @@ -3524,10 +3549,10 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(        return Result;    } -  return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, -                                         NumExplicitlySpecified, Specialization, -                                         Info, &OriginalCallArgs, -                                         PartialOverloading); +  return FinishTemplateArgumentDeduction( +      FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, +      &OriginalCallArgs, PartialOverloading, +      [&]() { return CheckNonDependent(ParamTypesForArgChecking); });  }  QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, | 

