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 1/2] 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 2/2] 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; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits