https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754
>From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/22] initial template arg fix push --- .../clang/Basic/DiagnosticSemaKinds.td | 4 +- clang/include/clang/Sema/TemplateDeduction.h | 5 ++ clang/lib/Sema/SemaOverload.cpp | 56 +++++++++++++++---- clang/lib/Sema/SemaTemplateDeduction.cpp | 8 +++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8be4f946dce1cc..1456f34538bcc0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4871,8 +4871,8 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; def note_ovl_candidate_explicit_arg_mismatch_named : Note< - "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0">; + "template argument deduction/substitution failed:" + "error: could not convert '%0' from %1 to %2">; def note_ovl_candidate_unsatisfied_constraints : Note< "candidate template ignored: constraints not satisfied%0">; def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index 28b014fd84e4b3..9edd3724cf53cd 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -250,6 +250,9 @@ class TemplateDeductionInfo { /// \brief The constraint satisfaction details resulting from the associated /// constraints satisfaction tests. ConstraintSatisfaction AssociatedConstraintsSatisfaction; + + /// \brief Type supplied by user for deduction + TemplateArgument SuppliedType; }; } // namespace sema @@ -300,6 +303,8 @@ struct DeductionFailureInfo { TemplateDeductionResult getResult() const { return static_cast<TemplateDeductionResult>(Result); } + + const TemplateArgument *getSuppliedType(); }; /// TemplateSpecCandidate - This is a generalization of OverloadCandidate diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 34c287926b1d7d..6c437a52be21db 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -715,12 +715,18 @@ namespace { struct DFIParamWithArguments : DFIArguments { TemplateParameter Param; }; + // Structure used by DeductionFailureInfo to store template argument // information and the index of the problematic call argument. struct DFIDeducedMismatchArgs : DFIArguments { TemplateArgumentList *TemplateArgs; unsigned CallArgIndex; }; + + struct DFIParamWithArgumentsAndSuppliedType : DFIArguments { + TemplateParameter Param; + TemplateArgument SuppliedType; + }; // Structure used by DeductionFailureInfo to store information about // unsatisfied constraints. struct CNSInfo { @@ -736,8 +742,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, TemplateDeductionResult TDK, TemplateDeductionInfo &Info) { DeductionFailureInfo Result; + Result.Result = static_cast<unsigned>(TDK); Result.HasDiagnostic = false; + switch (TDK) { case TemplateDeductionResult::Invalid: case TemplateDeductionResult::InstantiationDepth: @@ -749,10 +757,9 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; case TemplateDeductionResult::Incomplete: - case TemplateDeductionResult::InvalidExplicitArguments: + // case TemplateDeductionResult::InvalidExplicitArguments: Result.Data = Info.Param.getOpaqueValue(); break; - case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. @@ -777,6 +784,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, case TemplateDeductionResult::IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; @@ -786,6 +794,16 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Saved; break; } + case TemplateDeductionResult::InvalidExplicitArguments: { + DFIParamWithArgumentsAndSuppliedType *Saved = + new (Context) DFIParamWithArgumentsAndSuppliedType; + Saved->Param = Info.Param; + Saved->FirstArg = Info.FirstArg; + Saved->SecondArg = Info.SecondArg; + Saved->SuppliedType = Info.SuppliedType; + Result.Data = Saved; + break; + } case TemplateDeductionResult::SubstitutionFailure: Result.Data = Info.takeSugared(); @@ -822,13 +840,14 @@ void DeductionFailureInfo::Destroy() { case TemplateDeductionResult::Incomplete: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - case TemplateDeductionResult::InvalidExplicitArguments: + // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: break; case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: @@ -885,11 +904,11 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { return TemplateParameter(); case TemplateDeductionResult::Incomplete: - case TemplateDeductionResult::InvalidExplicitArguments: return TemplateParameter::getFromOpaqueValue(Data); case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: return static_cast<DFIParamWithArguments*>(Data)->Param; @@ -938,6 +957,16 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { return nullptr; } +const TemplateArgument *DeductionFailureInfo::getSuppliedType() { + switch (static_cast<TemplateDeductionResult>(Result)) { + case TemplateDeductionResult::InvalidExplicitArguments: + return &static_cast<DFIParamWithArgumentsAndSuppliedType *>(Data) + ->SuppliedType; + default: + return nullptr; + } +} + const TemplateArgument *DeductionFailureInfo::getFirstArg() { switch (static_cast<TemplateDeductionResult>(Result)) { case TemplateDeductionResult::Success: @@ -946,15 +975,17 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case TemplateDeductionResult::Incomplete: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - case TemplateDeductionResult::InvalidExplicitArguments: + // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::SubstitutionFailure: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; - + // case TemplateDeductionResult::InvalidExplicitArguments: //move back up + // there^^ case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: @@ -979,7 +1010,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - case TemplateDeductionResult::InvalidExplicitArguments: + // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::SubstitutionFailure: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: @@ -987,6 +1018,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { return nullptr; case TemplateDeductionResult::Inconsistent: + case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: @@ -11613,6 +11645,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) || (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) || (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>()); + switch (DeductionFailure.getResult()) { case TemplateDeductionResult::Success: llvm_unreachable( @@ -11716,11 +11749,14 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, case TemplateDeductionResult::InvalidExplicitArguments: assert(ParamD && "no parameter found for invalid explicit arguments"); - if (ParamD->getDeclName()) + if (ParamD->getDeclName()) { + auto FirstArg = *DeductionFailure.getFirstArg(); + auto SecondArg = *DeductionFailure.getSecondArg(); + auto SuppliedType = *DeductionFailure.getSuppliedType(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); - else { + << FirstArg << SuppliedType << SecondArg; + } else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD)) index = TTP->getIndex(); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 1c1f6e30ab7b83..92415d49ee7a49 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3575,7 +3575,15 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; + Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); + Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); + Info.SecondArg = TemplateArgument( + dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index)) + ->getType()); + Info.SuppliedType = TemplateArgument( + ExplicitTemplateArgs[Index].getSourceExpression()->getType()); + return TemplateDeductionResult::InvalidExplicitArguments; } >From e3a60c1f0adbf1801d51ab4d7834469349c0382a Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Tue, 14 Jan 2025 11:41:17 -0500 Subject: [PATCH 02/22] Improved safety, added some rt checks --- clang/lib/Sema/SemaTemplateDeduction.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 92415d49ee7a49..521e0da3ef2f92 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -766,6 +766,12 @@ static TemplateParameter makeTemplateParameter(Decl *D) { return TemplateParameter(cast<TemplateTemplateParmDecl>(D)); } +// Helper function to make template argument +static TemplateArgument makeTemplateArgument(Decl *D) { + if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) + return TemplateArgument(NTTP->getType()); + return TemplateArgument(); +} /// A pack that we're currently deducing. struct clang::DeducedPack { @@ -3578,11 +3584,19 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); - Info.SecondArg = TemplateArgument( - dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index)) - ->getType()); - Info.SuppliedType = TemplateArgument( - ExplicitTemplateArgs[Index].getSourceExpression()->getType()); + Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index)); + // Info.SecondArg = TemplateArgument( + // dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index)) + // ->getType()); + + // NonTypeTemplateParmDecl tmp = + // makeTemplateArgument(TemplateParams->getParam(Index)); if(!tmp.isNull()){ + // Info.SecondArg = tmp->getType(); + // } + if (ExplicitTemplateArgs[Index].getArgument().getKind() == + TemplateArgument::Expression) + Info.SuppliedType = TemplateArgument( + ExplicitTemplateArgs[Index].getSourceExpression()->getType()); return TemplateDeductionResult::InvalidExplicitArguments; } >From 86d44be78faaac1439977ea0ae2f8a213ca28aa3 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Wed, 15 Jan 2025 16:51:10 -0500 Subject: [PATCH 03/22] Fixed error message formatting --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1456f34538bcc0..0afba2ad681319 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4871,8 +4871,8 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; def note_ovl_candidate_explicit_arg_mismatch_named : Note< - "template argument deduction/substitution failed:" - "error: could not convert '%0' from %1 to %2">; + "candidate template ignored: invalid explicitly-specified argument " + "could not convert '%0' from %1 to %2">; def note_ovl_candidate_unsatisfied_constraints : Note< "candidate template ignored: constraints not satisfied%0">; def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< >From 9c1210d7a711a5324a10cba8af770028244cf34d Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 15:49:02 -0500 Subject: [PATCH 04/22] Update logic and tests --- .../clang/Basic/DiagnosticSemaKinds.td | 18 ++- clang/lib/Sema/SemaOverload.cpp | 133 ++++++++++++++++-- clang/lib/Sema/SemaTemplateDeduction.cpp | 46 ++++-- clang/test/CXX/drs/cwg2xx.cpp | 6 +- clang/test/CXX/expr/expr.const/p3-0x.cpp | 2 +- clang/test/SemaCXX/nullptr-98.cpp | 2 +- .../test/SemaTemplate/overload-candidates.cpp | 4 +- .../SemaTemplate/temp_arg_nontype_cxx11.cpp | 2 +- 8 files changed, 180 insertions(+), 33 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0afba2ad681319..a6110d14564e83 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4870,9 +4870,25 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "candidate template ignored: deduced values %diff{" "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; + def note_ovl_candidate_explicit_arg_mismatch_named : Note< "candidate template ignored: invalid explicitly-specified argument " - "could not convert '%0' from %1 to %2">; + "for template parameter %0: ">; + +def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< + "candidate template ignored: invalid explicitly-specified argument " + "for template parameter %0: " + "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">; + +def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note< + "candidate template ignored: invalid explicitly-specified argument " + "for template parameter %0: " + "could not convert '%1' from %2 to %3">; +def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note< + "candidate template ignored: invalid explicitly-specified argument " + "for template parameter %0: " + "expected constant of type %1 got type %2">; + def note_ovl_candidate_unsatisfied_constraints : Note< "candidate template ignored: constraints not satisfied%0">; def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6c437a52be21db..e1e5bdd268ef49 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -902,7 +902,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return TemplateParameter(); - + // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Incomplete: return TemplateParameter::getFromOpaqueValue(Data); @@ -11641,10 +11641,27 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, unsigned NumArgs, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); + int form; NamedDecl *ParamD; - (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) || - (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) || - (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>()); + TemplateTypeParmDecl *TTPD; + NonTypeTemplateParmDecl *NTTPD; + TemplateTemplateParmDecl *TTempPD; + if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl *>())) { + llvm::dbgs() << "case 1" << '\n'; + TTPD = cast<TemplateTypeParmDecl>(ParamD); + form = 1; + } else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>())) { + llvm::dbgs() << "case 2" << '\n'; + NTTPD = cast<NonTypeTemplateParmDecl>(ParamD); + form = 2; + } else if ((ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>())) { + llvm::dbgs() << "case 3" << '\n'; + TTempPD = cast<TemplateTemplateParmDecl>(ParamD); + form = 3; + } else { + llvm::dbgs() << "case 0" << '\n'; + form = 0; + } switch (DeductionFailure.getResult()) { case TemplateDeductionResult::Success: @@ -11747,15 +11764,108 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::InvalidExplicitArguments: { assert(ParamD && "no parameter found for invalid explicit arguments"); + if (ParamD->getDeclName()) { - auto FirstArg = *DeductionFailure.getFirstArg(); - auto SecondArg = *DeductionFailure.getSecondArg(); - auto SuppliedType = *DeductionFailure.getSuppliedType(); - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << FirstArg << SuppliedType << SecondArg; + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string SecondArg = ParamD->getNameAsString(); + TemplateArgument SuppliedType = *DeductionFailure.getSuppliedType(); + // llvm::dbgs() << ParamD->getNameAsString() << '\n'; + // llvm::dbgs() << ParamD->getDeclName().getAsString() << '\n'; + // llvm::dbgs() << ParamD->getQualifiedNameAsString() << '\n'; + // llvm::dbgs() << ParamD->getUnderlyingDecl()->getNameAsString() << '\n'; + // llvm::dbgs() << NTTPD->getType() << '\n'; + // llvm::dbgs() << '\n'; + // FirstArg.dump(); + // llvm::dbgs() << '\n'; + // SuppliedType.dump(); + // llvm::dbgs() << '\n'; + // llvm::dbgs() << SecondArg << '\n'; + switch (form) { + + // TemplateTypeParmDecl + case 1: { + // could not convert '42' from 'int' to TypeParam T + assert(TTPD); + TTPD->dump(); + if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SuppliedType << SecondArg + << "type"; + else { + // TODO write tests for type constrained classes + if (auto *constraint = TTPD->getTypeConstraint()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SuppliedType + << SecondArg << "valid type-constrained class"; + else + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SuppliedType + << SecondArg << "class"; + } + break; + } + // NonTypeTemplateParmDecl + case 2: { + assert(NTTPD); + if (SuppliedType.isNull()) { + // Expected constant of type 'int', got type 'int' + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp) + << ParamD->getDeclName() << FirstArg << NTTPD->getType(); + } else { + // Could not convert A from B to C + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp) + << ParamD->getDeclName() << FirstArg << SuppliedType + << NTTPD->getType(); + } + break; + } + case 3: { + assert(TTempPD); + // FirstArg.dump(); + // llvm::dbgs() << SecondArg << '\n' << SuppliedType.isNull() << '\n'; + // llvm::dbgs() << TTempPD->getDefaultArgument().getTypeSourceInfo() << + // '\n'; + + // expected a template of type 'template<class> class T', got + // 'template<class T1, class T2> struct InvalidTemplate' + + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << ParamD->getDeclName(); + break; + } + default: + llvm_unreachable("unexpected case"); + } + + // auto SecondArg = *DeductionFailure.getSecondArg(); + + // S.Diag(Templated->getLocation(), + // diag::note_ovl_candidate_explicit_arg_mismatch_named) + // << FirstArg << SuppliedType << SecondArg; + // if(SecondArg.isNull()){ + // S.Diag(Templated->getLocation(), + // diag::note_ovl_candidate_explicit_arg_mismatch_named) + // << FirstArg << SuppliedType << ParamD->getDeclName(); + // } + // else if(SuppliedType.isNull()){ + // S.Diag(Templated->getLocation(), + // diag::note_ovl_candidate_explicit_arg_mismatch_named) + // << FirstArg << "SuppliedTypeNull" << SecondArg; + // } + // else{ + // S.Diag(Templated->getLocation(), + // diag::note_ovl_candidate_explicit_arg_mismatch_named) + // << FirstArg << SuppliedType << SecondArg; + // } + } else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD)) @@ -11771,6 +11881,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, } MaybeEmitInheritedConstructorNote(S, Found); return; + } case TemplateDeductionResult::ConstraintsNotSatisfied: { // Format the template argument list into the argument string. diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 521e0da3ef2f92..d36d8b7fb250f5 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -768,8 +768,12 @@ static TemplateParameter makeTemplateParameter(Decl *D) { } // Helper function to make template argument static TemplateArgument makeTemplateArgument(Decl *D) { - if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) + if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>( + D)) // I in template<int I, typename T> return TemplateArgument(NTTP->getType()); + // if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D)) // T in + // template<int I, typename T> + // return TemplateArgument(TTP); return TemplateArgument(); } @@ -3582,21 +3586,37 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; + /* + + template<int I, typename T> //TemplateParams + void get(const T&); + + void test_get(void *ptr) { + get<int>(ptr); //TemplateArgs + } + */ Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index)); - // Info.SecondArg = TemplateArgument( - // dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index)) - // ->getType()); - - // NonTypeTemplateParmDecl tmp = - // makeTemplateArgument(TemplateParams->getParam(Index)); if(!tmp.isNull()){ - // Info.SecondArg = tmp->getType(); - // } - if (ExplicitTemplateArgs[Index].getArgument().getKind() == - TemplateArgument::Expression) - Info.SuppliedType = TemplateArgument( - ExplicitTemplateArgs[Index].getSourceExpression()->getType()); + // FunctionTemplate->dump(); + // Info.SuppliedType = makeTemplateArgument(TemplateParams->getParam(1)); + // llvm::dbgs() << TemplateParams->getParam(1) << '\n' << + // TemplateParams->getParam(1)->getNameAsString(); llvm::dbgs() << + // TemplateParams->size() << ExplicitTemplateArgs.size() << + // ParamTypes.size() << Deduced.size() << DeducedArgs.size() << "\n"; + + switch (ExplicitTemplateArgs[Index].getArgument().getKind()) { + case TemplateArgument::Expression: + Info.SuppliedType = + ExplicitTemplateArgs[Index].getSourceExpression()->getType(); + break; + case TemplateArgument::Type: + Info.SuppliedType = + TemplateArgument(); // ExplicitTemplateArgs[Index].getArgument(); + break; + default: + break; + } return TemplateDeductionResult::InvalidExplicitArguments; } diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index 0d644bae783828..08180c70faad63 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9 A::g<3>(b); C::f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} C::g<3>(b); // expected-error@-1 {{no matching function for call to 'g'}} - // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}} + // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} using C::f; using C::g; f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}} g<3>(b); } diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp index 5bd70c5250b598..c8e96ef963e5f8 100644 --- a/clang/test/CXX/expr/expr.const/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -105,7 +105,7 @@ void c() { break; } } -template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}} +template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B': could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}} template int f<&S::operator int>(); // expected-error {{does not refer to a function template}} template int f<(bool)&S::operator int>(); diff --git a/clang/test/SemaCXX/nullptr-98.cpp b/clang/test/SemaCXX/nullptr-98.cpp index 306b2033e45688..fbbceb90d1d9fc 100644 --- a/clang/test/SemaCXX/nullptr-98.cpp +++ b/clang/test/SemaCXX/nullptr-98.cpp @@ -1,4 +1,4 @@ // RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s // expected-no-diagnostics void f(void *); -void g() { f(__nullptr); } +void g() { f(__nullptr); } \ No newline at end of file diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp index de998d74f9af60..abfd896a611ba4 100644 --- a/clang/test/SemaTemplate/overload-candidates.cpp +++ b/clang/test/SemaTemplate/overload-candidates.cpp @@ -17,7 +17,7 @@ void test_dyn_cast(int* ptr) { } template<int I, typename T> - void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}} + void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' got type 'int'}} template<template<class T> class, typename T> void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}} @@ -163,4 +163,4 @@ namespace PR15673 { CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)> void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}} void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}} -} +} \ No newline at end of file diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp index 5752cbac0291d6..50ae078867534b 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp @@ -43,7 +43,7 @@ void TempFunc() {} void Useage() { //expected-error@+2 {{no matching function}} - //expected-note@-4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b'}} + //expected-note@-4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b': could not convert '-1' from 'int' to 'unsigned int'}} TempFunc<1, -1, 1>(); } } >From 4aca9d7247380f945757044aeddd906a04d75f6e Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 18:55:31 -0500 Subject: [PATCH 05/22] Cleaned up code, removed suppliedType --- clang/include/clang/Sema/TemplateDeduction.h | 5 - clang/lib/Sema/SemaOverload.cpp | 134 +++---------------- clang/lib/Sema/SemaTemplateDeduction.cpp | 42 +----- 3 files changed, 23 insertions(+), 158 deletions(-) diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index 9edd3724cf53cd..28b014fd84e4b3 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -250,9 +250,6 @@ class TemplateDeductionInfo { /// \brief The constraint satisfaction details resulting from the associated /// constraints satisfaction tests. ConstraintSatisfaction AssociatedConstraintsSatisfaction; - - /// \brief Type supplied by user for deduction - TemplateArgument SuppliedType; }; } // namespace sema @@ -303,8 +300,6 @@ struct DeductionFailureInfo { TemplateDeductionResult getResult() const { return static_cast<TemplateDeductionResult>(Result); } - - const TemplateArgument *getSuppliedType(); }; /// TemplateSpecCandidate - This is a generalization of OverloadCandidate diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e1e5bdd268ef49..e1fed0e9c9e9e4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -723,10 +723,6 @@ namespace { unsigned CallArgIndex; }; - struct DFIParamWithArgumentsAndSuppliedType : DFIArguments { - TemplateParameter Param; - TemplateArgument SuppliedType; - }; // Structure used by DeductionFailureInfo to store information about // unsatisfied constraints. struct CNSInfo { @@ -795,12 +791,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } case TemplateDeductionResult::InvalidExplicitArguments: { - DFIParamWithArgumentsAndSuppliedType *Saved = - new (Context) DFIParamWithArgumentsAndSuppliedType; + DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; Saved->Param = Info.Param; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; - Saved->SuppliedType = Info.SuppliedType; Result.Data = Saved; break; } @@ -902,10 +896,8 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return TemplateParameter(); - // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Incomplete: return TemplateParameter::getFromOpaqueValue(Data); - case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: @@ -937,7 +929,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: return nullptr; - case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs; @@ -957,16 +948,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { return nullptr; } -const TemplateArgument *DeductionFailureInfo::getSuppliedType() { - switch (static_cast<TemplateDeductionResult>(Result)) { - case TemplateDeductionResult::InvalidExplicitArguments: - return &static_cast<DFIParamWithArgumentsAndSuppliedType *>(Data) - ->SuppliedType; - default: - return nullptr; - } -} - const TemplateArgument *DeductionFailureInfo::getFirstArg() { switch (static_cast<TemplateDeductionResult>(Result)) { case TemplateDeductionResult::Success: @@ -975,14 +956,11 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case TemplateDeductionResult::Incomplete: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::SubstitutionFailure: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; - // case TemplateDeductionResult::InvalidExplicitArguments: //move back up - // there^^ case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: @@ -1010,13 +988,11 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::SubstitutionFailure: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; - case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: @@ -11641,27 +11617,11 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, unsigned NumArgs, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); - int form; NamedDecl *ParamD; - TemplateTypeParmDecl *TTPD; - NonTypeTemplateParmDecl *NTTPD; - TemplateTemplateParmDecl *TTempPD; - if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl *>())) { - llvm::dbgs() << "case 1" << '\n'; - TTPD = cast<TemplateTypeParmDecl>(ParamD); - form = 1; - } else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>())) { - llvm::dbgs() << "case 2" << '\n'; - NTTPD = cast<NonTypeTemplateParmDecl>(ParamD); - form = 2; - } else if ((ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>())) { - llvm::dbgs() << "case 3" << '\n'; - TTempPD = cast<TemplateTemplateParmDecl>(ParamD); - form = 3; - } else { - llvm::dbgs() << "case 0" << '\n'; - form = 0; - } + + (ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) || + (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) || + (ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>()); switch (DeductionFailure.getResult()) { case TemplateDeductionResult::Success: @@ -11769,50 +11729,30 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, if (ParamD->getDeclName()) { TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); - std::string SecondArg = ParamD->getNameAsString(); - TemplateArgument SuppliedType = *DeductionFailure.getSuppliedType(); - // llvm::dbgs() << ParamD->getNameAsString() << '\n'; - // llvm::dbgs() << ParamD->getDeclName().getAsString() << '\n'; - // llvm::dbgs() << ParamD->getQualifiedNameAsString() << '\n'; - // llvm::dbgs() << ParamD->getUnderlyingDecl()->getNameAsString() << '\n'; - // llvm::dbgs() << NTTPD->getType() << '\n'; - // llvm::dbgs() << '\n'; - // FirstArg.dump(); - // llvm::dbgs() << '\n'; - // SuppliedType.dump(); - // llvm::dbgs() << '\n'; - // llvm::dbgs() << SecondArg << '\n'; - switch (form) { - - // TemplateTypeParmDecl - case 1: { - // could not convert '42' from 'int' to TypeParam T - assert(TTPD); - TTPD->dump(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) { if (TTPD->wasDeclaredWithTypename()) S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SuppliedType << SecondArg + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName << "type"; else { // TODO write tests for type constrained classes if (auto *constraint = TTPD->getTypeConstraint()) S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SuppliedType - << SecondArg << "valid type-constrained class"; + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "valid type-constrained class"; else S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SuppliedType - << SecondArg << "class"; + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "class"; } - break; - } - // NonTypeTemplateParmDecl - case 2: { - assert(NTTPD); - if (SuppliedType.isNull()) { + } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) { + if (SecondArg.isNull()) { // Expected constant of type 'int', got type 'int' S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp) @@ -11821,51 +11761,15 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, // Could not convert A from B to C S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp) - << ParamD->getDeclName() << FirstArg << SuppliedType + << ParamD->getDeclName() << FirstArg << SecondArg << NTTPD->getType(); } - break; - } - case 3: { - assert(TTempPD); - // FirstArg.dump(); - // llvm::dbgs() << SecondArg << '\n' << SuppliedType.isNull() << '\n'; - // llvm::dbgs() << TTempPD->getDefaultArgument().getTypeSourceInfo() << - // '\n'; - - // expected a template of type 'template<class> class T', got - // 'template<class T1, class T2> struct InvalidTemplate' - + } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) << ParamD->getDeclName(); - break; - } - default: + } else llvm_unreachable("unexpected case"); - } - - // auto SecondArg = *DeductionFailure.getSecondArg(); - - // S.Diag(Templated->getLocation(), - // diag::note_ovl_candidate_explicit_arg_mismatch_named) - // << FirstArg << SuppliedType << SecondArg; - // if(SecondArg.isNull()){ - // S.Diag(Templated->getLocation(), - // diag::note_ovl_candidate_explicit_arg_mismatch_named) - // << FirstArg << SuppliedType << ParamD->getDeclName(); - // } - // else if(SuppliedType.isNull()){ - // S.Diag(Templated->getLocation(), - // diag::note_ovl_candidate_explicit_arg_mismatch_named) - // << FirstArg << "SuppliedTypeNull" << SecondArg; - // } - // else{ - // S.Diag(Templated->getLocation(), - // diag::note_ovl_candidate_explicit_arg_mismatch_named) - // << FirstArg << SuppliedType << SecondArg; - // } - } else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD)) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index d36d8b7fb250f5..806da4ba240c49 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -766,16 +766,6 @@ static TemplateParameter makeTemplateParameter(Decl *D) { return TemplateParameter(cast<TemplateTemplateParmDecl>(D)); } -// Helper function to make template argument -static TemplateArgument makeTemplateArgument(Decl *D) { - if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>( - D)) // I in template<int I, typename T> - return TemplateArgument(NTTP->getType()); - // if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D)) // T in - // template<int I, typename T> - // return TemplateArgument(TTP); - return TemplateArgument(); -} /// A pack that we're currently deducing. struct clang::DeducedPack { @@ -3586,37 +3576,13 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; - /* - - template<int I, typename T> //TemplateParams - void get(const T&); - - void test_get(void *ptr) { - get<int>(ptr); //TemplateArgs - } - */ Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); - Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index)); - // FunctionTemplate->dump(); - // Info.SuppliedType = makeTemplateArgument(TemplateParams->getParam(1)); - // llvm::dbgs() << TemplateParams->getParam(1) << '\n' << - // TemplateParams->getParam(1)->getNameAsString(); llvm::dbgs() << - // TemplateParams->size() << ExplicitTemplateArgs.size() << - // ParamTypes.size() << Deduced.size() << DeducedArgs.size() << "\n"; - - switch (ExplicitTemplateArgs[Index].getArgument().getKind()) { - case TemplateArgument::Expression: - Info.SuppliedType = + Info.SecondArg = TemplateArgument(); + if (ExplicitTemplateArgs[Index].getArgument().getKind() == + TemplateArgument::Expression) + Info.SecondArg = ExplicitTemplateArgs[Index].getSourceExpression()->getType(); - break; - case TemplateArgument::Type: - Info.SuppliedType = - TemplateArgument(); // ExplicitTemplateArgs[Index].getArgument(); - break; - default: - break; - } return TemplateDeductionResult::InvalidExplicitArguments; } >From 9c10aa953002243cf9ffbb9f99fd0ec94e503169 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 18:58:39 -0500 Subject: [PATCH 06/22] removed newlines diagnosticSemKinds.td --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a6110d14564e83..ea1013f7ef7b7e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4870,16 +4870,13 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "candidate template ignored: deduced values %diff{" "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; - def note_ovl_candidate_explicit_arg_mismatch_named : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: ">; - def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">; - def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " @@ -4888,7 +4885,6 @@ def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " "expected constant of type %1 got type %2">; - def note_ovl_candidate_unsatisfied_constraints : Note< "candidate template ignored: constraints not satisfied%0">; def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< >From 35d79a7e6224684f9d6e81b839ac0ab1947cfc4e Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <47676355+aidangoldf...@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:03:00 -0500 Subject: [PATCH 07/22] Update clang/lib/Sema/SemaOverload.cpp Co-authored-by: Justin Fargnoli <jfargn...@nvidia.com> --- clang/lib/Sema/SemaOverload.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e1fed0e9c9e9e4..61564ed4f1ca20 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11618,7 +11618,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) || (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) || (ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>()); >From babe495ac378a49440b1fa2de80b0cea4d026b3e Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <47676355+aidangoldf...@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:03:10 -0500 Subject: [PATCH 08/22] Update clang/lib/Sema/SemaOverload.cpp Co-authored-by: Justin Fargnoli <jfargn...@nvidia.com> --- clang/lib/Sema/SemaOverload.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 61564ed4f1ca20..63b63c85d1d84c 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11725,7 +11725,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, case TemplateDeductionResult::InvalidExplicitArguments: { assert(ParamD && "no parameter found for invalid explicit arguments"); - if (ParamD->getDeclName()) { TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); std::string ParamName = ParamD->getNameAsString(); >From 7984368fbf47884f378bb6af80c03b3dc5a495c1 Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <47676355+aidangoldf...@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:03:33 -0500 Subject: [PATCH 09/22] Update clang/test/SemaCXX/nullptr-98.cpp Co-authored-by: Justin Fargnoli <jfargn...@nvidia.com> --- clang/test/SemaCXX/nullptr-98.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/nullptr-98.cpp b/clang/test/SemaCXX/nullptr-98.cpp index fbbceb90d1d9fc..306b2033e45688 100644 --- a/clang/test/SemaCXX/nullptr-98.cpp +++ b/clang/test/SemaCXX/nullptr-98.cpp @@ -1,4 +1,4 @@ // RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s // expected-no-diagnostics void f(void *); -void g() { f(__nullptr); } \ No newline at end of file +void g() { f(__nullptr); } >From 13607304b7a608a01e39de1d5ad8abba27d1a752 Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <47676355+aidangoldf...@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:04:40 -0500 Subject: [PATCH 10/22] Apply suggestions from code review Co-authored-by: Justin Fargnoli <jfargn...@nvidia.com> --- clang/lib/Sema/SemaOverload.cpp | 3 --- clang/lib/Sema/SemaTemplateDeduction.cpp | 1 - clang/test/SemaTemplate/overload-candidates.cpp | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 63b63c85d1d84c..aa64f631dbe44d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -753,7 +753,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; case TemplateDeductionResult::Incomplete: - // case TemplateDeductionResult::InvalidExplicitArguments: Result.Data = Info.Param.getOpaqueValue(); break; case TemplateDeductionResult::DeducedMismatch: @@ -780,7 +779,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, case TemplateDeductionResult::IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. case TemplateDeductionResult::Inconsistent: - case TemplateDeductionResult::Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; @@ -834,7 +832,6 @@ void DeductionFailureInfo::Destroy() { case TemplateDeductionResult::Incomplete: case TemplateDeductionResult::TooManyArguments: case TemplateDeductionResult::TooFewArguments: - // case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: break; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 806da4ba240c49..18f82ef0b936a0 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3575,7 +3575,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; - Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); Info.SecondArg = TemplateArgument(); diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp index abfd896a611ba4..bc181c7942402c 100644 --- a/clang/test/SemaTemplate/overload-candidates.cpp +++ b/clang/test/SemaTemplate/overload-candidates.cpp @@ -163,4 +163,4 @@ namespace PR15673 { CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)> void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}} void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}} -} \ No newline at end of file +} >From ffdc1b6fce146748107a7828f0f02920e68c163b Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 19:10:10 -0500 Subject: [PATCH 11/22] some newlines removed --- clang/lib/Sema/SemaOverload.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index aa64f631dbe44d..5400f4cdcfc934 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -715,14 +715,12 @@ namespace { struct DFIParamWithArguments : DFIArguments { TemplateParameter Param; }; - // Structure used by DeductionFailureInfo to store template argument // information and the index of the problematic call argument. struct DFIDeducedMismatchArgs : DFIArguments { TemplateArgumentList *TemplateArgs; unsigned CallArgIndex; }; - // Structure used by DeductionFailureInfo to store information about // unsatisfied constraints. struct CNSInfo { @@ -738,10 +736,8 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, TemplateDeductionResult TDK, TemplateDeductionInfo &Info) { DeductionFailureInfo Result; - Result.Result = static_cast<unsigned>(TDK); Result.HasDiagnostic = false; - switch (TDK) { case TemplateDeductionResult::Invalid: case TemplateDeductionResult::InstantiationDepth: >From b22f2390fe2bbde7daab9cd72ceb73d20be265a6 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 19:12:41 -0500 Subject: [PATCH 12/22] some newlines added --- clang/lib/Sema/SemaOverload.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5400f4cdcfc934..13be184267c1cc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -889,8 +889,10 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return TemplateParameter(); + case TemplateDeductionResult::Incomplete: return TemplateParameter::getFromOpaqueValue(Data); + case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: @@ -922,6 +924,7 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { case TemplateDeductionResult::CUDATargetMismatch: case TemplateDeductionResult::NonDependentConversionFailure: return nullptr; + case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs; @@ -954,6 +957,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; + case TemplateDeductionResult::IncompletePack: case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: @@ -986,6 +990,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case TemplateDeductionResult::NonDependentConversionFailure: case TemplateDeductionResult::ConstraintsNotSatisfied: return nullptr; + case TemplateDeductionResult::Inconsistent: case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::Underqualified: >From 170825651d8bf1897f592e21b5ab9a2ab488b033 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Mon, 20 Jan 2025 19:15:14 -0500 Subject: [PATCH 13/22] a newline added --- clang/lib/Sema/SemaOverload.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 13be184267c1cc..6c14535176886f 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -751,6 +751,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, case TemplateDeductionResult::Incomplete: Result.Data = Info.Param.getOpaqueValue(); break; + case TemplateDeductionResult::DeducedMismatch: case TemplateDeductionResult::DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. >From 256d22b0cf7c81279030b1f3da936efc29824298 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Tue, 21 Jan 2025 10:38:46 -0500 Subject: [PATCH 14/22] more cleanup --- clang/lib/Sema/SemaOverload.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6c14535176886f..856b2fe5c7b4bc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -773,6 +773,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, break; } + case TemplateDeductionResult::InvalidExplicitArguments: case TemplateDeductionResult::IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. case TemplateDeductionResult::Inconsistent: @@ -785,14 +786,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Saved; break; } - case TemplateDeductionResult::InvalidExplicitArguments: { - DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; - Saved->Param = Info.Param; - Saved->FirstArg = Info.FirstArg; - Saved->SecondArg = Info.SecondArg; - Result.Data = Saved; - break; - } case TemplateDeductionResult::SubstitutionFailure: Result.Data = Info.takeSugared(); >From 8a7ce10e282af2104c78635a4d1cd1f7c7ff72b4 Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <agold...@u.rochester.edu> Date: Wed, 22 Jan 2025 14:59:54 -0500 Subject: [PATCH 15/22] Apply suggestions from code review Co-authored-by: Justin Fargnoli <jfargn...@nvidia.com> --- clang/lib/Sema/SemaOverload.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 856b2fe5c7b4bc..559d4c26b7fdc4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11610,10 +11610,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) || - (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) || - (ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>()); - + (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) || + (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) || + (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>()); switch (DeductionFailure.getResult()) { case TemplateDeductionResult::Success: llvm_unreachable( >From 29491ec15180f650fabc6d2a7a79aa5dc625d6ad Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Wed, 22 Jan 2025 18:58:51 -0500 Subject: [PATCH 16/22] remove unneeded diag --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++-- clang/lib/Sema/SemaOverload.cpp | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ea1013f7ef7b7e..a30caebc8fb2fd 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4877,11 +4877,11 @@ def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">; -def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note< +def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " "could not convert '%1' from %2 to %3">; -def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note< +def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " "expected constant of type %1 got type %2">; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 559d4c26b7fdc4..ef6d820ed6a6bc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11728,12 +11728,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, << ParamD->getDeclName() << FirstArg << SecondArg << ParamName << "type"; else { - // TODO write tests for type constrained classes - if (auto *constraint = TTPD->getTypeConstraint()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SecondArg << ParamName - << "valid type-constrained class"; + if (TTPD->getTypeConstraint()) + llvm_unreachable("ill-formed program"); else S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) @@ -11744,16 +11740,17 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, if (SecondArg.isNull()) { // Expected constant of type 'int', got type 'int' S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp) + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a) << ParamD->getDeclName() << FirstArg << NTTPD->getType(); } else { // Could not convert A from B to C S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp) + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b) << ParamD->getDeclName() << FirstArg << SecondArg << NTTPD->getType(); } } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) { + TTempPD->dump(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) << ParamD->getDeclName(); >From 11fb7499e762bde2fb7fc792cd11256401028b3a Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Fri, 24 Jan 2025 13:32:18 -0500 Subject: [PATCH 17/22] cleaned up code --- .../clang/Basic/DiagnosticSemaKinds.td | 4 ++-- clang/lib/Sema/SemaOverload.cpp | 21 +++++++++---------- clang/lib/Sema/SemaTemplateDeduction.cpp | 1 - 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a30caebc8fb2fd..3016677fc33a75 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4870,9 +4870,9 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "candidate template ignored: deduced values %diff{" "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; -def note_ovl_candidate_explicit_arg_mismatch_named : Note< +def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note< "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0: ">; + "for template parameter %0">; def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index ef6d820ed6a6bc..f8987306fac780 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11728,31 +11728,30 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, << ParamD->getDeclName() << FirstArg << SecondArg << ParamName << "type"; else { - if (TTPD->getTypeConstraint()) - llvm_unreachable("ill-formed program"); - else - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SecondArg << ParamName - << "class"; + // Concept satisfied but not modeled => ill-formed + assert(!TTPD->getTypeConstraint() && + "Concept satisfied but not modeled"); + + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "class"; } } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) { if (SecondArg.isNull()) { - // Expected constant of type 'int', got type 'int' S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a) << ParamD->getDeclName() << FirstArg << NTTPD->getType(); } else { - // Could not convert A from B to C S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b) << ParamD->getDeclName() << FirstArg << SecondArg << NTTPD->getType(); } } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) { - TTempPD->dump(); + // FIXME: Emit a better message here S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) + diag::note_ovl_candidate_explicit_arg_mismatch_named_temptemppd) << ParamD->getDeclName(); } else llvm_unreachable("unexpected case"); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 18f82ef0b936a0..74e9c45b4e8c42 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3577,7 +3577,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); - Info.SecondArg = TemplateArgument(); if (ExplicitTemplateArgs[Index].getArgument().getKind() == TemplateArgument::Expression) Info.SecondArg = >From 2acdb18a3c1b93f893d94a6c473473923d6c76cb Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Tue, 28 Jan 2025 15:03:15 -0500 Subject: [PATCH 18/22] simplified ttpd case and updated test --- .../include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaOverload.cpp | 18 +++--------------- clang/test/CXX/drs/cwg2xx.cpp | 6 +++--- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3016677fc33a75..b80e67a4b8f071 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4876,7 +4876,7 @@ def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note< def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " - "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">; + "expectd a type, but got value '%1' (of type %2)">; def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f8987306fac780..82fa00ca014f7f 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11722,21 +11722,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) { - if (TTPD->wasDeclaredWithTypename()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SecondArg << ParamName - << "type"; - else { - // Concept satisfied but not modeled => ill-formed - assert(!TTPD->getTypeConstraint() && - "Concept satisfied but not modeled"); - - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SecondArg << ParamName - << "class"; - } + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg; } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) { if (SecondArg.isNull()) { S.Diag(Templated->getLocation(), diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index 08180c70faad63..28fb9d86d4ff9c 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9 A::g<3>(b); C::f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} C::g<3>(b); // expected-error@-1 {{no matching function for call to 'g'}} - // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} + // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} using C::f; using C::g; f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}} g<3>(b); } >From b36ff68a3f1404052080c3c0066c1c6a78ca924d Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <agold...@u.rochester.edu> Date: Tue, 28 Jan 2025 15:24:19 -0500 Subject: [PATCH 19/22] Fixed type Co-authored-by: Matheus Izvekov <mizve...@gmail.com> --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b80e67a4b8f071..b0d1298d095322 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4876,7 +4876,7 @@ def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note< def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " - "expectd a type, but got value '%1' (of type %2)">; + "expected a type, but got value '%1' (of type %2)">; def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0: " >From 6db7a7a98d0c378efa89cc33a5bde6ba74103522 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Tue, 28 Jan 2025 15:25:46 -0500 Subject: [PATCH 20/22] typo fixed --- clang/test/CXX/drs/cwg2xx.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index 28fb9d86d4ff9c..2373b769b91722 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9 A::g<3>(b); C::f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}} C::g<3>(b); // expected-error@-1 {{no matching function for call to 'g'}} - // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} + // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}} using C::f; using C::g; f<3>(b); // expected-error@-1 {{no matching function for call to 'f'}} - // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}} + // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}} // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}} g<3>(b); } >From fc7fec12efc2a1cf951922fa6f49a572a6021295 Mon Sep 17 00:00:00 2001 From: Aidan <aidan.goldf...@mail.mcgill.ca> Date: Tue, 28 Jan 2025 20:49:39 -0500 Subject: [PATCH 21/22] merged diag defs into one --- .../clang/Basic/DiagnosticSemaKinds.td | 20 ++++++------------- clang/lib/Sema/SemaOverload.cpp | 17 ++++++++-------- .../test/SemaTemplate/overload-candidates.cpp | 2 +- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b0d1298d095322..19af6eb6c6aaf9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4870,21 +4870,13 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "candidate template ignored: deduced values %diff{" "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|" "%1 and %3 of conflicting types for parameter %0}2,4">; -def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note< +def note_ovl_candidate_explicit_arg_mismatch_named : Note< "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0">; -def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note< - "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0: " - "expected a type, but got value '%1' (of type %2)">; -def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note< - "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0: " - "could not convert '%1' from %2 to %3">; -def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a : Note< - "candidate template ignored: invalid explicitly-specified argument " - "for template parameter %0: " - "expected constant of type %1 got type %2">; + "for template parameter %1%select{" + "|: expected a type, but got value '%2' (of type %3)" + "|: could not convert '%2' from %3 to %4" + "|: expected constant of type %2 but got type %3" + "|}0">; def note_ovl_candidate_unsatisfied_constraints : Note< "candidate template ignored: constraints not satisfied%0">; def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 82fa00ca014f7f..486e050aede16e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11723,24 +11723,25 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) { S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) - << ParamD->getDeclName() << FirstArg << SecondArg; + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 1 << ParamD->getDeclName() << FirstArg << SecondArg; + } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) { if (SecondArg.isNull()) { S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a) - << ParamD->getDeclName() << FirstArg << NTTPD->getType(); + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 3 << ParamD->getDeclName() << NTTPD->getType() << FirstArg; } else { S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b) - << ParamD->getDeclName() << FirstArg << SecondArg + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 2 << ParamD->getDeclName() << FirstArg << SecondArg << NTTPD->getType(); } } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) { // FIXME: Emit a better message here S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named_temptemppd) - << ParamD->getDeclName(); + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 4 << ParamD->getDeclName(); } else llvm_unreachable("unexpected case"); } else { diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp index bc181c7942402c..98ed02d8e92930 100644 --- a/clang/test/SemaTemplate/overload-candidates.cpp +++ b/clang/test/SemaTemplate/overload-candidates.cpp @@ -17,7 +17,7 @@ void test_dyn_cast(int* ptr) { } template<int I, typename T> - void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' got type 'int'}} + void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' but got type 'int'}} template<template<class T> class, typename T> void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}} >From b578b870dd6d65a945b63a84fcd5c93c1ee0daba Mon Sep 17 00:00:00 2001 From: Aidan Goldfarb <agold...@u.rochester.edu> Date: Wed, 29 Jan 2025 10:29:07 -0500 Subject: [PATCH 22/22] Apply suggestions from code review Co-authored-by: Matheus Izvekov <mizve...@gmail.com> --- clang/lib/Sema/SemaOverload.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 486e050aede16e..5b2f7734f81c27 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -11718,7 +11718,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, assert(ParamD && "no parameter found for invalid explicit arguments"); if (ParamD->getDeclName()) { TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); - std::string ParamName = ParamD->getNameAsString(); TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) { @@ -11743,7 +11742,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, diag::note_ovl_candidate_explicit_arg_mismatch_named) << 4 << ParamD->getDeclName(); } else - llvm_unreachable("unexpected case"); + llvm_unreachable("unexpected param decl kind"); } else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD)) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits