Author: rsmith Date: Sun Jan 8 19:18:18 2017 New Revision: 291412 URL: http://llvm.org/viewvc/llvm-project?rev=291412&view=rev Log: Revert r291410 and r291411.
The test-suite bots are still failing even after r291410's fix. Modified: cfe/trunk/include/clang/Sema/Overload.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/test/CXX/drs/dr13xx.cpp cfe/trunk/test/Misc/diag-template-diffing.cpp cfe/trunk/test/SemaCXX/attr-mode-tmpl.cpp cfe/trunk/test/SemaCXX/attr-noreturn.cpp cfe/trunk/test/SemaCXX/overload-call.cpp cfe/trunk/test/SemaCXX/overload-member-call.cpp cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp cfe/trunk/www/cxx_dr_status.html Modified: cfe/trunk/include/clang/Sema/Overload.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Overload.h (original) +++ cfe/trunk/include/clang/Sema/Overload.h Sun Jan 8 19:18:18 2017 @@ -531,13 +531,6 @@ namespace clang { Ambiguous.construct(); } - void setAsIdentityConversion(QualType T) { - setStandard(); - Standard.setAsIdentityConversion(); - Standard.setFromType(T); - Standard.setAllToTypes(T); - } - /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool isStdInitializerListElement() const { @@ -614,11 +607,6 @@ namespace clang { ovl_fail_inhctor_slice, }; - /// A list of implicit conversion sequences for the arguments of an - /// OverloadCandidate. - typedef llvm::MutableArrayRef<ImplicitConversionSequence> - ConversionSequenceList; - /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). struct OverloadCandidate { /// Function - The actual function that this candidate @@ -643,13 +631,18 @@ namespace clang { /// is a surrogate, but only if IsSurrogate is true. CXXConversionDecl *Surrogate; - /// The conversion sequences used to convert the function arguments - /// to the function parameters. - ConversionSequenceList Conversions; + /// Conversions - The conversion sequences used to convert the + /// function arguments to the function parameters, the pointer points to a + /// fixed size array with NumConversions elements. The memory is owned by + /// the OverloadCandidateSet. + ImplicitConversionSequence *Conversions; /// The FixIt hints which can be used to fix the Bad candidate. ConversionFixItGenerator Fix; + /// NumConversions - The number of elements in the Conversions array. + unsigned NumConversions; + /// Viable - True to indicate that this overload candidate is viable. bool Viable; @@ -688,9 +681,9 @@ namespace clang { /// hasAmbiguousConversion - Returns whether this overload /// candidate requires an ambiguous conversion or not. bool hasAmbiguousConversion() const { - for (auto &C : Conversions) { - if (!C.isInitialized()) return false; - if (C.isAmbiguous()) return true; + for (unsigned i = 0, e = NumConversions; i != e; ++i) { + if (!Conversions[i].isInitialized()) return false; + if (Conversions[i].isAmbiguous()) return true; } return false; } @@ -739,7 +732,7 @@ namespace clang { SmallVector<OverloadCandidate, 16> Candidates; llvm::SmallPtrSet<Decl *, 16> Functions; - // Allocator for ConversionSequenceLists. We store the first few + // Allocator for OverloadCandidate::Conversions. We store the first few // elements inline to avoid allocation for small sets. llvm::BumpPtrAllocator ConversionSequenceAllocator; @@ -780,45 +773,30 @@ namespace clang { size_t size() const { return Candidates.size(); } bool empty() const { return Candidates.empty(); } - /// \brief Allocate storage for conversion sequences for NumConversions - /// conversions. - ConversionSequenceList - allocateConversionSequences(unsigned NumConversions) { - ImplicitConversionSequence *Conversions; + /// \brief Add a new candidate with NumConversions conversion sequence slots + /// to the overload set. + OverloadCandidate &addCandidate(unsigned NumConversions = 0) { + Candidates.push_back(OverloadCandidate()); + OverloadCandidate &C = Candidates.back(); // Assign space from the inline array if there are enough free slots // available. if (NumConversions + NumInlineSequences <= 16) { ImplicitConversionSequence *I = (ImplicitConversionSequence *)InlineSpace.buffer; - Conversions = &I[NumInlineSequences]; + C.Conversions = &I[NumInlineSequences]; NumInlineSequences += NumConversions; } else { // Otherwise get memory from the allocator. - Conversions = - ConversionSequenceAllocator.Allocate<ImplicitConversionSequence>( - NumConversions); + C.Conversions = ConversionSequenceAllocator + .Allocate<ImplicitConversionSequence>(NumConversions); } // Construct the new objects. - for (unsigned I = 0; I != NumConversions; ++I) - new (&Conversions[I]) ImplicitConversionSequence(); + for (unsigned i = 0; i != NumConversions; ++i) + new (&C.Conversions[i]) ImplicitConversionSequence(); - return ConversionSequenceList(Conversions, NumConversions); - } - - /// \brief Add a new candidate with NumConversions conversion sequence slots - /// to the overload set. - OverloadCandidate &addCandidate(unsigned NumConversions = 0, - ConversionSequenceList Conversions = None) { - assert((Conversions.empty() || Conversions.size() == NumConversions) && - "preallocated conversion sequence has wrong length"); - - Candidates.push_back(OverloadCandidate()); - OverloadCandidate &C = Candidates.back(); - C.Conversions = Conversions.empty() - ? allocateConversionSequences(NumConversions) - : Conversions; + C.NumConversions = NumConversions; return C; } Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Sun Jan 8 19:18:18 2017 @@ -120,7 +120,6 @@ namespace clang { class FunctionProtoType; class FunctionTemplateDecl; class ImplicitConversionSequence; - typedef MutableArrayRef<ImplicitConversionSequence> ConversionSequenceList; class InitListExpr; class InitializationKind; class InitializationSequence; @@ -2519,11 +2518,10 @@ public: void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, + OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, bool PartialOverloading = false, - bool AllowExplicit = false, - ConversionSequenceList EarlyConversions = None); + bool AllowExplicit = false); void AddFunctionCandidates(const UnresolvedSetImpl &Functions, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, @@ -2543,8 +2541,7 @@ public: ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, - bool PartialOverloading = false, - ConversionSequenceList EarlyConversions = None); + bool PartialOverloading = false); void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -2562,16 +2559,6 @@ public: OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, bool PartialOverloading = false); - bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate, - ArrayRef<QualType> ParamTypes, - ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, - ConversionSequenceList &Conversions, - bool SuppressUserConversions, - CXXRecordDecl *ActingContext = nullptr, - QualType ObjectType = QualType(), - Expr::Classification - ObjectClassification = {}); void AddConversionCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -6604,8 +6591,6 @@ public: /// \brief The explicitly-specified template arguments were not valid /// template arguments for the given template. TDK_InvalidExplicitArguments, - /// \brief Checking non-dependent argument conversions failed. - TDK_NonDependentConversionFailure, /// \brief Deduction failed; that's all we know. TDK_MiscellaneousDeductionFailure, /// \brief CUDA Target attributes do not match. @@ -6644,21 +6629,22 @@ public: QualType OriginalArgType; }; - TemplateDeductionResult FinishTemplateArgumentDeduction( - FunctionTemplateDecl *FunctionTemplate, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info, - SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, - bool PartialOverloading = false, - llvm::function_ref<bool()> CheckNonDependent = []{ return false; }); + TemplateDeductionResult + FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, + unsigned NumExplicitlySpecified, + FunctionDecl *&Specialization, + sema::TemplateDeductionInfo &Info, + SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, + bool PartialOverloading = false); - TemplateDeductionResult DeduceTemplateArguments( - FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, - FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, - bool PartialOverloading, - llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent); + TemplateDeductionResult + DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, + TemplateArgumentListInfo *ExplicitTemplateArgs, + ArrayRef<Expr *> Args, + FunctionDecl *&Specialization, + sema::TemplateDeductionInfo &Info, + bool PartialOverloading = false); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Jan 8 19:18:18 2017 @@ -589,6 +589,7 @@ clang::MakeDeductionFailureInfo(ASTConte 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: @@ -644,10 +645,6 @@ clang::MakeDeductionFailureInfo(ASTConte Result.HasDiagnostic = true; } break; - - case Sema::TDK_Success: - case Sema::TDK_NonDependentConversionFailure: - llvm_unreachable("not a deduction failure"); } return Result; @@ -663,7 +660,6 @@ void DeductionFailureInfo::Destroy() { case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: break; case Sema::TDK_Inconsistent: @@ -708,7 +704,6 @@ TemplateParameter DeductionFailureInfo:: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return TemplateParameter(); case Sema::TDK_Incomplete: @@ -740,7 +735,6 @@ TemplateArgumentList *DeductionFailureIn case Sema::TDK_Underqualified: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_DeducedMismatch: @@ -769,7 +763,6 @@ const TemplateArgument *DeductionFailure case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: @@ -798,7 +791,6 @@ const TemplateArgument *DeductionFailure case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: @@ -829,8 +821,8 @@ llvm::Optional<unsigned> DeductionFailur 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(); } @@ -5837,8 +5829,7 @@ Sema::AddOverloadCandidate(FunctionDecl 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"); @@ -5857,7 +5848,7 @@ Sema::AddOverloadCandidate(FunctionDecl 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 @@ -5890,8 +5881,7 @@ Sema::AddOverloadCandidate(FunctionDecl 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; @@ -5955,10 +5945,7 @@ Sema::AddOverloadCandidate(FunctionDecl // 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 @@ -6292,8 +6279,7 @@ Sema::AddMethodCandidate(CXXMethodDecl * 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"); @@ -6314,8 +6300,7 @@ Sema::AddMethodCandidate(CXXMethodDecl * 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; @@ -6377,10 +6362,7 @@ Sema::AddMethodCandidate(CXXMethodDecl * // 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 @@ -6441,30 +6423,19 @@ Sema::AddMethodTemplateCandidate(Functio // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - 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); + 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; } @@ -6475,8 +6446,7 @@ Sema::AddMethodTemplateCandidate(Functio "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 @@ -6504,29 +6474,19 @@ Sema::AddTemplateOverloadCandidate(Funct // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - 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); + 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; } @@ -6534,65 +6494,7 @@ Sema::AddTemplateOverloadCandidate(Funct // 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<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<unsigned>(FD->getNumParams(), 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; + SuppressUserConversions, PartialOverloading); } /// Determine whether this is an allowable conversion from the result @@ -8831,8 +8733,8 @@ bool clang::isBetterOverloadCandidate(Se // 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]); @@ -10031,7 +9933,7 @@ static void NoteFunctionCandidate(Sema & 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); @@ -10100,12 +10002,12 @@ static void NoteSurrogateCandidate(Sema 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 { @@ -10118,7 +10020,9 @@ static void NoteBuiltinOperatorCandidate 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; @@ -10138,8 +10042,7 @@ static SourceLocation GetLocationForCand 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: @@ -10242,11 +10145,11 @@ struct CompareOverloadCandidatesForDispl // 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])) { @@ -10295,8 +10198,7 @@ struct CompareOverloadCandidatesForDispl } /// 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); @@ -10309,24 +10211,30 @@ static void CompleteNonViableCandidate(S // 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 @@ -10334,56 +10242,40 @@ static void CompleteNonViableCandidate(S 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(); } } Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sun Jan 8 19:18:18 2017 @@ -2893,13 +2893,14 @@ static unsigned getPackIndexForParam(Sem /// /// \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); @@ -2926,18 +2927,6 @@ Sema::TemplateDeductionResult Sema::Fini 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); @@ -3384,19 +3373,12 @@ static Sema::TemplateDeductionResult Ded /// \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, - llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) { + bool PartialOverloading) { if (FunctionTemplate->isInvalidDecl()) return TDK_Invalid; @@ -3515,10 +3497,10 @@ Sema::TemplateDeductionResult Sema::Dedu break; } - return FinishTemplateArgumentDeduction( - FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, - [&]() { return CheckNonDependent(ParamTypes); }); + return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, + NumExplicitlySpecified, Specialization, + Info, &OriginalCallArgs, + PartialOverloading); } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, Modified: cfe/trunk/test/CXX/drs/dr13xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr13xx.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr13xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr13xx.cpp Sun Jan 8 19:18:18 2017 @@ -174,81 +174,3 @@ namespace dr1359 { // dr1359: 3.5 constexpr Y y = Y(); // expected-error {{no matching}} #endif } - -namespace dr1391 { // dr1391: partial - struct A {}; struct B : A {}; - template<typename T> struct C { C(int); typename T::error error; }; // expected-error 2{{'::'}} - template<typename T> struct D {}; - - // No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match. - template<typename T> void a(T, int T::*); - void test_a(int A::*p) { a(A(), p); } // ok, type of second parameter does not need to match - - namespace dr_example_1 { - template<typename T, typename U> void f(C<T>); - template<typename T> void f(D<T>); - - void g(D<int> d) { - f(d); // ok, first 'f' eliminated by deduction failure - f<int>(d); // ok, first 'f' eliminated because 'U' cannot be deduced - } - } - - namespace dr_example_2 { - template<typename T> typename C<T>::error f(int, T); - template<typename T> T f(T, T); - - void g(A a) { - f(a, a); // ok, no conversion from A to int for first parameter of first candidate - } - } - - namespace std_example { - template<typename T> struct Z { - typedef typename T::x xx; - }; - template<typename T> typename Z<T>::xx f(void *, T); - template<typename T> void f(int, T); - struct A {} a; - void g() { f(1, a); } - } - - template<typename T> void b(C<int> ci, T *p); - void b(...); - void test_b() { - b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int> - // FIXME: The "while substituting" note should point at the overload candidate. - b<int>(0, 0); // expected-note {{instantiation of}} expected-note {{while substituting}} - } - - template<typename T> struct Id { typedef T type; }; - template<typename T> void c(T, typename Id<C<T> >::type); - void test_c() { - // Implicit conversion sequences for dependent types are checked later. - c(0.0, 0); // expected-note {{instantiation of}} - } - - namespace partial_ordering { - // FIXME: Second template should be considered more specialized because non-dependent parameter is ignored. - template<typename T> int a(T, short) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}} - template<typename T> int a(T*, char); // expected-note {{candidate}} - int test_a = a((int*)0, 0); // FIXME: expected-error {{ambiguous}} - - // FIXME: Second template should be considered more specialized: - // deducing #1 from #2 ignores the second P/A pair, so deduction succeeds, - // deducing #2 from #1 fails to deduce T, so deduction fails. - template<typename T> int b(T, int) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}} - template<typename T, typename U> int b(T*, U); // expected-note {{candidate}} - int test_b = b((int*)0, 0); // FIXME: expected-error {{ambiguous}} - - // Unintended consequences: because partial ordering does not consider - // explicit template arguments, and deduction from a non-dependent type - // vacuously succeeds, a non-dependent template is less specialized than - // anything else! - // According to DR1391, this is ambiguous! - template<typename T> int c(int); - template<typename T> int c(T); - int test_c1 = c(0); // ok - int test_c2 = c<int>(0); // FIXME: apparently ambiguous - } -} Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/Misc/diag-template-diffing.cpp (original) +++ cfe/trunk/test/Misc/diag-template-diffing.cpp Sun Jan 8 19:18:18 2017 @@ -1265,7 +1265,7 @@ void test() { foo<BoolT<true>>(X); } // CHECK-ELIDE-NOTREE: no matching function for call to 'foo' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'BoolT<false>' to 'BoolT<true>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function [with T = BoolArgumentBitExtended::BoolT<true>] not viable: no known conversion from 'BoolT<false>' to 'BoolT<true>' for 1st argument } namespace DifferentIntegralTypes { @@ -1401,7 +1401,7 @@ void run() { f(1, integral_constant<bool, true>{}); } // CHECK-ELIDE-NOTREE: error: no matching function for call to 'f' -// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'integral_constant<[...], true>' to 'integral_constant<[...], false>' for 2nd argument +// CHECK-ELIDE-NOTREE: note: candidate function [with T = int] not viable: no known conversion from 'integral_constant<[...], true>' to 'integral_constant<[...], false>' for 2nd argument } namespace ZeroArgs { @@ -1454,7 +1454,7 @@ void run() { D<X::X1>(VectorType<X::X2>()); } // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D' -// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument +// CHECK-ELIDE-NOTREE: note: candidate function [with x = TypeAlias::X::X1] not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument } namespace TypeAlias2 { Modified: cfe/trunk/test/SemaCXX/attr-mode-tmpl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-mode-tmpl.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/attr-mode-tmpl.cpp (original) +++ cfe/trunk/test/SemaCXX/attr-mode-tmpl.cpp Sun Jan 8 19:18:18 2017 @@ -45,7 +45,7 @@ void CheckMachineMode() { // Check attributes on function parameters. template <class T1, class T2> -void CheckParameters(T1 __attribute__((mode(SI))) paramSI, // expected-note{{ignored: substitution failure}} expected-note-re{{not viable: no known conversion from '{{.*}}' (vector of 4 '{{.*}}' values) to 'EnumType' for 2nd argument}} +void CheckParameters(T1 __attribute__((mode(SI))) paramSI, // expected-note2{{ignored: substitution failure}} T1 __attribute__((mode(V4DI))) paramV4DI, // expected-warning{{deprecated}} T2 __attribute__((mode(SF))) paramSF, T2 __attribute__((mode(V4DF))) paramV4DF) { // expected-warning{{deprecated}} Modified: cfe/trunk/test/SemaCXX/attr-noreturn.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-noreturn.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/attr-noreturn.cpp (original) +++ cfe/trunk/test/SemaCXX/attr-noreturn.cpp Sun Jan 8 19:18:18 2017 @@ -244,11 +244,11 @@ namespace PR15291 { template <typename T> void qux(T) {} - // expected-note@+5 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+4 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+3 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} - // expected-note@+2 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} - // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} + // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} + // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} template <typename T> void accept_T(T) {} // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} Modified: cfe/trunk/test/SemaCXX/overload-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-call.cpp Sun Jan 8 19:18:18 2017 @@ -338,7 +338,7 @@ namespace PR5756 { // Tests the exact text used to note the candidates namespace test1 { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} Modified: cfe/trunk/test/SemaCXX/overload-member-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-member-call.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-member-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-member-call.cpp Sun Jan 8 19:18:18 2017 @@ -70,7 +70,7 @@ void test_X2(X2 *x2p, const X2 *cx2p) { // Tests the exact text used to note the candidates namespace test1 { class A { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp (original) +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp Sun Jan 8 19:18:18 2017 @@ -173,16 +173,12 @@ namespace pr6249 { } namespace PR6723 { - template<unsigned char C> void f(int (&a)[C]); // expected-note 3{{candidate template ignored: substitution failure [with C = '\x00']}} - // expected-note@-1 {{not viable: no known conversion from 'int [512]' to 'int (&)[0]'}} + template<unsigned char C> void f(int (&a)[C]); // expected-note {{candidate template ignored}} \ + // expected-note{{substitution failure [with C = '\x00']}} void g() { int arr512[512]; f(arr512); // expected-error{{no matching function for call}} f<512>(arr512); // expected-error{{no matching function for call}} - - int arr0[0]; - f(arr0); // expected-error{{no matching function for call}} - f<0>(arr0); // expected-error{{no matching function for call}} } } Modified: cfe/trunk/www/cxx_dr_status.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=291412&r1=291411&r2=291412&view=diff ============================================================================== --- cfe/trunk/www/cxx_dr_status.html (original) +++ cfe/trunk/www/cxx_dr_status.html Sun Jan 8 19:18:18 2017 @@ -8161,7 +8161,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1391">1391</a></td> <td>DRWP</td> <td>Conversions to parameter types with non-deduced template arguments</td> - <td class="partial" align="center">Partial</td> + <td class="none" align="center">Unknown</td> </tr> <tr id="1392"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1392">1392</a></td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits