[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
mizvekov wrote: Yeah, I agree, renaming the other one to what you proposed sounds good to me. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
mizvekov wrote: Sorry about that, but the patch which added the automatic `NoteTemplateParameterLocation` was reverted and I had missed the notification. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
AidanGoldfarb wrote: > If you can't, or otherwise this new signature doesn't make sense for the > pre-existing callers, you should create a new result kind instead. You propose creating a new result kind for [this user](https://github.com/AidanGoldfarb/llvm-project/blob/main/clang/lib/Sema/SemaTemplateDeduction.cpp#L4567C11-L4567C68)? This is the one that seems improperly named to me. Would something like `InvalidExplicitObject` be better here? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -3572,10 +3572,17 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SugaredBuilder, CanonicalBuilder, /*UpdateArgsWithConversions=*/false) || Trap.hasErrorOccurred()) { + unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); +Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); +if (ExplicitTemplateArgs[Index].getArgument().getKind() == +TemplateArgument::Expression) + Info.SecondArg = + ExplicitTemplateArgs[Index].getSourceExpression()->getType(); mizvekov wrote: If you can't, or otherwise this new signature doesn't make sense for the pre-existing callers, you should create a new result kind instead. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/mizvekov edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -35,31 +35,27 @@ namespace ConstDestruction { constexpr ~D() { if (!can_destroy) -throw "oh no"; // expected-note {{subexpression not valid}} +throw "oh no"; } }; - template - void f() {} // expected-note 2{{invalid explicitly-specified argument}} + template // expected-note 2{{template parameter is declared here}} + void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument}} void g() { f(); f(); // expected-error {{no matching function}} } // We can SFINAE on constant destruction. - template auto h(T t) -> decltype(f()); - template auto h(T t) -> decltype(f()); + // template auto h(T t) -> decltype(f()); + // template auto h(T t) -> decltype(f()); void i() { -h(D()); +//h(D()); // Ensure we don't cache an invalid template argument after we've already // seen it in a SFINAE context. f(); // expected-error {{no matching function}} f(); } - - template struct Z {}; - Z z1; - Z z2; // expected-error {{non-type template argument is not a constant expression}} expected-note-re {{in call to '{{.*}}.~D()'}} mizvekov wrote: What is up with these commented and removed tests? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/mizvekov commented: This needs a rebase, I believe because of one of my patches. Just remove the call to 'S.NoteTemplateParameterLocation(*ParamD);', since that note is now emitted automatically. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -3572,10 +3572,17 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SugaredBuilder, CanonicalBuilder, /*UpdateArgsWithConversions=*/false) || Trap.hasErrorOccurred()) { + unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); +Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); +if (ExplicitTemplateArgs[Index].getArgument().getKind() == +TemplateArgument::Expression) + Info.SecondArg = + ExplicitTemplateArgs[Index].getSourceExpression()->getType(); AidanGoldfarb wrote: By this do you mean in: `DeductionFailureInfo clang::MakeDeductionFailureInfo(...)` `void DeductionFailureInfo::Destroy()` ... `const TemplateArgument *DeductionFailureInfo::getSecondArg()` I tried to follow the pattern of `TemplateDeductionResult::Inconsistent`, as that uses similar parameters. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -3572,10 +3572,17 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SugaredBuilder, CanonicalBuilder, /*UpdateArgsWithConversions=*/false) || Trap.hasErrorOccurred()) { + unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); +Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); +if (ExplicitTemplateArgs[Index].getArgument().getKind() == +TemplateArgument::Expression) + Info.SecondArg = + ExplicitTemplateArgs[Index].getSourceExpression()->getType(); mizvekov wrote: I mean other code in clang which emits a InvalidExplicitArguments, will not currently be setting these new parameters. You need to make sure that makes sense and will not break anything, or otherwise change these users. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,17 @@ 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 : Note< +"candidate template ignored: invalid explicitly-specified argument" +"%select{" +"|: %select{non-type|type}1 argument %select{'%3'|%3}1 is not compatible with " +"%select{non-type|type}2 parameter %select{%5|%4}2" +"|: could not convert '%3' from %4 to %5" +"| for %ordinal6 template parameter}0">; mizvekov wrote: You don't need to talk about the parameter since we emit a separate note for it, that should make this diagnostic a bit simpler, as right now it's stretching it on complexity. If we are talking about argument / parameter kinds, it would make sense to talk about 'template' kind, besides non-type and type, otherwise some mismatches could happen between non-type kinds and that's a bit confusing. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -3572,10 +3572,17 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( SugaredBuilder, CanonicalBuilder, /*UpdateArgsWithConversions=*/false) || Trap.hasErrorOccurred()) { + unsigned Index = SugaredBuilder.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); +Info.FirstArg = ExplicitTemplateArgs[Index].getArgument(); +if (ExplicitTemplateArgs[Index].getArgument().getKind() == +TemplateArgument::Expression) + Info.SecondArg = + ExplicitTemplateArgs[Index].getSourceExpression()->getType(); mizvekov wrote: Since you are adding new parameters for a `InvalidExplicitArguments`, did you audit all the users, in order to include the new information as well? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,27 +11714,51 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { - int index = 0; - if (TemplateTypeParmDecl *TTP = dyn_cast(ParamD)) -index = TTP->getIndex(); - else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast(ParamD)) -index = NTTP->getIndex(); - else -index = cast(ParamD)->getIndex(); - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_unnamed) - << (index + 1); -} +TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); +TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + +auto TupleResult = [&]() -> std::tuple { + switch (ParamD->getKind()) { + case Decl::TemplateTypeParm: { +auto *TTPD = cast(ParamD); +return {1, 0, 1, TTPD->getIndex(), QualType()}; + } + case Decl::NonTypeTemplateParm: { +auto *NTTPD = cast(ParamD); +if (SecondArg.isNull()) { + return {1, 1, 0, NTTPD->getIndex(), NTTPD->getType()}; +} else { + // FIXME: This is a hack. We should emit a better message + // for ill-formed const exprs in >=C++20. + QualType qt = NTTPD->getType(); + if (qt.getCanonicalType() == + SecondArg.getAsType().getCanonicalType()) { +return {3, -1, -1, NTTPD->getIndex(), NTTPD->getType()}; + } else { +return {2, -1, -1, NTTPD->getIndex(), NTTPD->getType()}; + } +} + } + case Decl::TemplateTemplateParm: { +auto *TTempPD = cast(ParamD); +return {3, -1, -1, TTempPD->getIndex(), QualType()}; + } + default: +llvm_unreachable("unexpected param decl kind"); + } +}; +auto [Which, Provided, Expected, Index, Type] = TupleResult(); mizvekov wrote: I would drop the `TupleResult` thing and just immediately invoke and decompose the lambda. This would be fine for me and you don't need to change, but here is another idea in case you like it, or other people prefer it: ```suggestion SemaDiagnosticBuilder DB = S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch); switch (ParamD->getKind()) { case Decl::TemplateTypeParm: DB << 1 << 0 << 1 << cast(ParamD)->getIndex() << QualType(); break; ... } ``` And so on. You would need to introduce an extra scope here for 'DB', as it needs to be destroyed for the diagnostic to be emitted, and this needs to happen before we emit any notes. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,27 +11714,51 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { - int index = 0; - if (TemplateTypeParmDecl *TTP = dyn_cast(ParamD)) -index = TTP->getIndex(); - else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast(ParamD)) -index = NTTP->getIndex(); - else -index = cast(ParamD)->getIndex(); - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_unnamed) - << (index + 1); -} +TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); +TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + +auto TupleResult = [&]() -> std::tuple { + switch (ParamD->getKind()) { + case Decl::TemplateTypeParm: { +auto *TTPD = cast(ParamD); +return {1, 0, 1, TTPD->getIndex(), QualType()}; + } + case Decl::NonTypeTemplateParm: { +auto *NTTPD = cast(ParamD); +if (SecondArg.isNull()) { + return {1, 1, 0, NTTPD->getIndex(), NTTPD->getType()}; +} else { + // FIXME: This is a hack. We should emit a better message + // for ill-formed const exprs in >=C++20. + QualType qt = NTTPD->getType(); + if (qt.getCanonicalType() == + SecondArg.getAsType().getCanonicalType()) { +return {3, -1, -1, NTTPD->getIndex(), NTTPD->getType()}; + } else { +return {2, -1, -1, NTTPD->getIndex(), NTTPD->getType()}; + } +} + } + case Decl::TemplateTemplateParm: { +auto *TTempPD = cast(ParamD); +return {3, -1, -1, TTempPD->getIndex(), QualType()}; + } + default: +llvm_unreachable("unexpected param decl kind"); + } +}; +auto [Which, Provided, Expected, Index, Type] = TupleResult(); +S.NoteTemplateParameterLocation(*ParamD); +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch) +<< Which << Provided << Expected << FirstArg << SecondArg << Type +<< (Index + 1); mizvekov wrote: ```suggestion S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch) << Which << Provided << Expected << FirstArg << SecondArg << Type << (Index + 1); S.NoteTemplateParameterLocation(*ParamD); ``` The note must always come after the error, otherwise it becomes attached to whatever diagnostic we emitted previously. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" erichkeane wrote: `__cplusplus` isn't right here, that is a check against the compiler being used to compile clang, right? What we want is `getLangOpts().CPlusPlus17` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" AidanGoldfarb wrote: Updated the diags. I am not thrilled about ``` // FIXME: This is a hack. We should emit a better message // for ill-formed const exprs in >=C++20. if (qt.getCanonicalType() == SecondArg.getAsType().getCanonicalType() && __cplusplus <= 201703) ``` but I couldn't find another way to avoid the case. Would be resolved in a future PR, along with better messages for `TemplateTemplateParmDecl` cases. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; AidanGoldfarb wrote: Noted, thank you. I definitely want to dig into the issue, but I am happy to divert it to another PR per your advice. I will revert the relevant cases to their original messages (or whatever we determine the new default to be). For the test in `cwg3xx.cpp` that would be `candidate template ignored: invalid explicitly-specified argument for 1st template parameter` (the original unnamed case). https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; cor3ntin wrote: Poking at it, it seems that it would be pretty challenging to do. I don't think it's a good idea to try to do it in this PR - might be worth explore separately I think/hope TemplateDeductionResult has the info you want (diags_begin/diags_end) I think in `clang::MakeDeductionFailureInfo` you would want to extract more information from Info, like we do for `TemplateDeductionResult::SubstitutionFailure` - At least I'd try to explorer that. Again, maybe do that in a subsequent PR https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" AidanGoldfarb wrote: FYI: I plan to resolve this after the ill formed const expression business. The most recent push still contains tests which expect awkward error messages. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" AidanGoldfarb wrote: Ok, I now see well what you mean. I will clean up the messages and attempt to add the previously mentioned `constexpr` case https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" cor3ntin wrote: This is still too much information, which is why it is a bit awkward. When you pass a type to a value or the other way around (and don't forget the template parameter case), it does not matter what that type, or that value is. Which is why I proposed something like thar `non-type|type|template argument 'foo' is not compatible with non-type|type|template template parameter 'bar'` In particular it avoids the `expected constant of type int but got type int` - which is going be confusing for a lot of people (note that `expected constant of type int but got type char*` might arguably be even more misleading a one might think there is a conversion error when it fact the salient issue is that the argument and parameter are of different kinds altogether https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; AidanGoldfarb wrote: [GCC](https://godbolt.org/z/7ax4n77dv) provides some nice information IMO. I will try to make the output more imformative. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; mizvekov wrote: Thanks, that sounds like an improvement. Do we produce additional notes explaining why it's not a constant expression? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; AidanGoldfarb wrote: Implemented. I put the `NoteTemplateParameterLocation` call after the diag, so it appears as: ``` source.cpp:80:5: error: no matching function for call to 'foo' 80 | foo(); | ^~ 3 source.cpp:77:13: note: candidate template ignored: invalid explicitly-specified argument: could not convert 'false' from 'bool' to 'endianness' 77 | inline void foo() {} | ^ source.cpp:76:22: note: template parameter is declared here 76 | template | ^ ``` Let me know if that looks good. Separately, I found an interesting case that I had not caught before due to the more generic `//expected-note {{invalid explicitly-specified argument}}` allowing the confusing error message seen below. The case from `clang/test/CXX/temp/temp.param/p8-cxx20.cpp` ``` namespace ConstDestruction { struct D { int n; bool can_destroy; constexpr ~D() { if (!can_destroy) throw "oh no"; // expected-note {{subexpression not valid}} } }; template void f() {} // expected-note 2{{invalid explicitly-specified argument}} void g() { f(); f(); // expected-error {{no matching function}} } } ``` The root cause being an ill-formed constexpr. In this case, the diag message `candidate template ignored: invalid explicitly-specified argument: could not convert 'D{0, false}' from 'D' to 'D'` cannot be what we want. Although it is an invalid explicitly specified argument, it seems to be to be in a separate category from other tests. Should I look into emitting a unique error message along the lines of `template argument ‘D{0, false}’ is not a valid constant expression`? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; AidanGoldfarb wrote: I'll try that. This commit introduced some unexpected test failures, I believe because of this change. I will revisit soon, as well as your proposed lambda refactor. Thank you! https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,14 +4870,16 @@ 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 : Note< "candidate template ignored: invalid explicitly-specified argument " -"for template parameter %0">; +"for %ordinal0 template parameter">; +def note_ovl_candidate_explicit_arg_mismatch_detail : Note< +"%select{" +"|: expected a type, but got value '%1'" +"|: expected constant of type %3 but got type %1" +"|: could not convert '%1' from %2 to %3}0">; mizvekov wrote: Now the select is weird, as there is nothing besides it, so these are completely disjointed notes. The first select option would produce an empty diagnostic, but it's not used anyway. How about joining these diagnostics again, but take out the "for %ordinal0 template parameter" part, and do that as separate note, using the NoteTemplateParameterLocation function? https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,27 +11714,44 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { - int index = 0; - if (TemplateTypeParmDecl *TTP = dyn_cast(ParamD)) -index = TTP->getIndex(); - else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast(ParamD)) -index = NTTP->getIndex(); +int Which = 0; +int Index = 0; +TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); +TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); +QualType Type; +SourceRange SrcRange; + +if (auto *TTPD = dyn_cast(ParamD)) { + Which = 1; + Index = TTPD->getIndex(); + SrcRange = TTPD->getSourceRange(); +} else if (auto *NTTPD = dyn_cast(ParamD)) { + if (SecondArg.isNull()) +Which = 2; mizvekov wrote: An immediately invoked lambda + decomposition might be cleaner, but it's up to you: ```suggestion auto [Which, Index, Type, SrcRange] = [] -> std::tuple { switch(ParamD->getKind()) { case Decl::TemplateTypeParm: { auto *TTPD = cast(ParamD); return {1, TTPD->getIndex(), QualType(), TTPD->getSourceRange()}; } case Decl::NonTypeTemplateParm: { ... } ... } llvm_unreachable("unexpected param decl kind"); }(); ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,38 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 1 << ParamD->getDeclName() << FirstArg << SecondArg +<< TTPD->getSourceRange(); + + } else if (auto *NTTPD = dyn_cast(ParamD)) { +if (SecondArg.isNull()) { + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 3 << ParamD->getDeclName() << NTTPD->getType() << FirstArg + << NTTPD->getSourceRange(); +} else { + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 2 << ParamD->getDeclName() << FirstArg << SecondArg + << NTTPD->getType() << NTTPD->getSourceRange(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { +// FIXME: Emit a better message here +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 4 << ParamD->getDeclName() << TTempPD->getSourceRange(); + } else +llvm_unreachable("unexpected param decl kind"); +} else { int index = 0; AidanGoldfarb wrote: With the last refactor I think the code is better, but its possible I blissfully ignored some coding practices... https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { AidanGoldfarb wrote: My most recent change split up the information into two diags, much like GCC and what I think you were suggesting. Please let me know if this was what you had in mind https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/24] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { cor3ntin wrote: if the kind doesn't match (ie type vs non-type or the other way around for example) we do not need to put the actual type or value in the diagnostic. That would simplify a lot. cf my previous suggestion. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { mizvekov wrote: I see, if you think that's too much information in one diagnostic, you can split that out. For example, we do already have a note for pointing out a template parameter for other diagnostics, see `NoteTemplateParameterLocation` in `clang/lib/Sema/SemaTemplate.cpp`. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { AidanGoldfarb wrote: Would it be redundant to print the index in all cases, even when we can point to it with SourceRange? Would we prefer a message like: ``` source.cpp:44:5: error: no matching function for call to 'case1' 44 | case1<42>(42); source.cpp:41:6: note: candidate template ignored: invalid explicitly-specified template argument: expected a type, but got value '42' (of type 'int') 40 | template | ~~ 41 | void case1(T value) {} | ^ ``` (The above is what I have implemented and am planning to push) over: ``` source.cpp:44:5: error: no matching function for call to 'case1' 44 | case1<42>(42); source.cpp:41:6: note: candidate template ignored: invalid explicitly-specified argument for 1st template parameter: expected a type, but got value '42' (of type 'int') 40 | template | ~~ 41 | void case1(T value) {} | ^ ``` Although perhaps obvious, I am asking because `candidate template ignored: invalid explicitly-specified template argument: expected a type, but got value '42' (of type 'int')` on its own doesn't give us any location information. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/mizvekov edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { mizvekov wrote: This bit about the highlight is in line with our best practices, to point things using source locations instead of printing them out. Printing the template name in addition to that is redundant and discouraged. Pointing them out with source locations now works even better in that it handles anonymous template parameters gracefully, so you could go beyond and remove the current fallback for that case. If it's even possible to not have a source location here, you could have a different fallback where now you print the name, or failing that, print the parameter index. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { AidanGoldfarb wrote: Just added. A current message is like this: ``` template void case1(T value) {} int main() { case1<42>(42); } ``` ``` source.cpp:44:5: error: no matching function for call to 'case1' 44 | case1<42>(42); source.cpp:41:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '42' (of type 'int') 40 | template | ~~ 41 | void case1(T value) {} | ^ ``` Perhaps it is a bit unclear having the highlight and caret on sequential lines, which both refer to the same function definition? If this format looks good I am happy to keep it, but I could foresee some confusion. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,38 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 1 << ParamD->getDeclName() << FirstArg << SecondArg +<< TTPD->getSourceRange(); + + } else if (auto *NTTPD = dyn_cast(ParamD)) { +if (SecondArg.isNull()) { + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 3 << ParamD->getDeclName() << NTTPD->getType() << FirstArg + << NTTPD->getSourceRange(); +} else { + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) + << 2 << ParamD->getDeclName() << FirstArg << SecondArg + << NTTPD->getType() << NTTPD->getSourceRange(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { +// FIXME: Emit a better message here +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 4 << ParamD->getDeclName() << TTempPD->getSourceRange(); + } else +llvm_unreachable("unexpected param decl kind"); +} else { int index = 0; mizvekov wrote: I think this is good, thanks! If you want to make this even better, here is another idea: 1) Remove this fallback diagnostic `diag::note_ovl_candidate_explicit_arg_mismatch_unnamed` entirely. 2) On the diagnostic above, you can select to print the name only in case the SourceRange is empty. Then in case the name is also empty, you print the index instead, as this fallback does. Like so, you avoid this degradation in diagnostics with unnamed template parameters, where currently your improvements don't apply to them. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/23] 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 8be4f946dce1ccb..1456f34538bcc07 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 28b014fd84e4b35..9edd3724cf53cdb 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(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 34c287926b1d7dc..6c437a52be21dbf 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(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.S
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { mizvekov wrote: Yeah, Diag has a source location parameter, but in addition to that, you can stream out a SourceRange, which will be highlighted in the diagnostic output. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/24] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/23] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { AidanGoldfarb wrote: My recent change improved the caret imo. I used `getEndLoc()`, I wasn't sure if there was a better way to capture `SourceRange` into a `SourceLocation` that Diag requires https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { mizvekov wrote: Something like: ```C++ S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) << 2 << FirstArg << SecondArg << NTTPD->getType() << NTTPD->getSourceRange(); ``` Ie remove the name, add the SourceRange. In clang diagnostics, we tend to avoid printing out things if we can just point to the source location instead. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,9 +4870,21 @@ 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">; +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">; AidanGoldfarb wrote: I believe I resolved this with the merging of diag messages, but I am not exactly sure what you mean. Please let me know if I misunderstood. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 1 << ParamD->getDeclName() << FirstArg << SecondArg; + + } else if (auto *NTTPD = dyn_cast(ParamD)) { +if (SecondArg.isNull()) { + S.Diag(Templated->getLocation(), + 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) + << 2 << ParamD->getDeclName() << FirstArg << SecondArg + << NTTPD->getType(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { +// FIXME: Emit a better message here +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< 4 << ParamD->getDeclName(); + } else +llvm_unreachable("unexpected case"); mizvekov wrote: ```suggestion llvm_unreachable("unexpected param decl kind"); ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { mizvekov wrote: Do we want to point the parameter out with a caret, instead or at least in addition to printing the decl name? You can keep the main diagnostic pointing to the template location as currently, but you could also forward the source range of the parameter to the diagnostic, and this should make it so the parameter gets highlighted. If the parameter is anonymous, as often happens, the diagnostic does not get degraded. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,37 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); mizvekov wrote: Unused: ```suggestion ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/21] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,9 +4870,21 @@ 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">; +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">; mizvekov wrote: These can be merged into one diagnostic like so: ```suggestion def note_ovl_candidate_explicit_arg_mismatch : Note< "candidate template ignored: invalid explicitly-specified argument " "for template parameter %0%select{|: expected a type, but got value '%1' (of type %2)|: could not convert '%1' from %2 to %3|expected constant of type %1 got type %2}">; ``` Basically the %select{choice1|choice2} parameter allows you to select one of multiple options there. You can see how this works by looking at the implementation of `note_ovl_candidate_illegal_constructor`. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,9 +4870,21 @@ 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">; +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">; cor3ntin wrote: I think the reason would be better as a separate note, amd all of these things could be merged ``` note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T' note: could not convert '-1' from 'int' to 'unsigned int' https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,9 +4870,21 @@ 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">; +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">; cor3ntin wrote: note: explicitly specified non-type|type|template argument 'Foo' is not compatible with non-type|type|template template parameter bar (I think that when the kind of template differs we don;t care about their value/type) https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/19] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/20] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4870,9 +4870,21 @@ 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">; +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)">; mizvekov wrote: ```suggestion "expected a type, but got value '%1' (of type %2)">; ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -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')}} AidanGoldfarb wrote: What you suggested is more like what GCC does, and I have updated it in my last patch, thanks! https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/18] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -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')}} Endilll wrote: Parentheses can be omitted in my suggestion, but the intent is to hammer on type parameter vs value argument mismatch. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/Endilll edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/Endilll edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/Endilll edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/Endilll commented: The way you applied changes to C++ DR tests is good, but I think the diagnostic message would benefit from further wordsmithing. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -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')}} Endilll wrote: The newly added diagnostic wording seems confusing to me, but the text in parentheses might be salvageable: ```suggestion // 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'))}} ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb ready_for_review https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb deleted https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb deleted https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb deleted https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -4872,7 +4872,19 @@ def note_ovl_candidate_inconsistent_deduction_types : Note< "%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">; +"for template parameter %0: ">; AidanGoldfarb wrote: resolved in last commit https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/17] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11714,49 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << 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"; +} + } else if (auto *NTTPD = dyn_cast(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(ParamD)) { +TTempPD->dump(); +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named) +<< ParamD->getDeclName(); AidanGoldfarb wrote: My initial thought was no, as we are casting a `NamedDecl` not a `TemplateParameter`. If the latter was case, one of the three casts would be guaranteed to succeed, but I am not sure if that is still the case with the former. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/16] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << 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"; + else +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(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) + << 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 << SecondArg + << NTTPD->getType(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { AidanGoldfarb wrote: Thank you for the suggestion. However, I am planning to at least attempt to make a better error message in this situation, so I would need this cast. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "type"; +else { + // TODO write tests for type constrained classes + if (auto *constraint = TTPD->getTypeConstraint()) AidanGoldfarb wrote: I am still not sure how I want to handle concepts, as [some information](https://en.cppreference.com/w/cpp/concepts) leads me to believe there should be no diagnostic at all (ill formed). I will make sure there is no unused variable when I ready the PR for review. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754 >From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001 From: Aidan Date: Mon, 13 Jan 2025 11:53:39 -0500 Subject: [PATCH 01/15] 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(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(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.SecondA
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + antoniofrighetto wrote: No strong concerns. However, since this change surrounds the code that's being added and only fixes a minor styling issue, I think it may be acceptable to address it in this commit—unless we have documentation that explicitly discourages doing so (I couldn’t find any mention of that). Should `@AidanGoldfarb` be willing to fix all related old-style issues in this file, it would make sense to have a dedicate commit. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + justinfargnoli wrote: @antoniofrighetto, similar to the change @AidanGoldfarb made to this code snippet, adding a space between the type and pointer is an NFC change that should be done in a separate commit. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << 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"; + else +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(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) + << 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 << SecondArg + << NTTPD->getType(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { antoniofrighetto wrote: ```suggestion } else if (isa(ParamD)) { ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ 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()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "type"; +else { + // TODO write tests for type constrained classes + if (auto *constraint = TTPD->getTypeConstraint()) antoniofrighetto wrote: ```suggestion if (TTPD->getTypeConstraint()) ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + antoniofrighetto wrote: Space between type and pointer. ```suggestion (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + justinfargnoli wrote: ```suggestion (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/AidanGoldfarb edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits