[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 [email protected] 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 [email protected] 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 [email protected] 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
[email protected]
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 [email protected] 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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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
[email protected]
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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
