[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
Aidan Goldfarb via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 26 08:20:27 PST 2025
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/122754
>From b6c576fb90362640b2fd4e41bd7f13dfee95d04d Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 13 Jan 2025 11:53:39 -0500
Subject: [PATCH 01/31] 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 8be4f946dce1c..1456f34538bcc 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 28b014fd84e4b..9edd3724cf53c 100644
--- a/clang/include/clang/Sema/TemplateDeduction.h
+++ b/clang/include/clang/Sema/TemplateDeduction.h
@@ -250,6 +250,9 @@ class TemplateDeductionInfo {
/// \brief The constraint satisfaction details resulting from the associated
/// constraints satisfaction tests.
ConstraintSatisfaction AssociatedConstraintsSatisfaction;
+
+ /// \brief Type supplied by user for deduction
+ TemplateArgument SuppliedType;
};
} // namespace sema
@@ -300,6 +303,8 @@ struct DeductionFailureInfo {
TemplateDeductionResult getResult() const {
return static_cast<TemplateDeductionResult>(Result);
}
+
+ const TemplateArgument *getSuppliedType();
};
/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 34c287926b1d7..6c437a52be21d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -715,12 +715,18 @@ namespace {
struct DFIParamWithArguments : DFIArguments {
TemplateParameter Param;
};
+
// Structure used by DeductionFailureInfo to store template argument
// information and the index of the problematic call argument.
struct DFIDeducedMismatchArgs : DFIArguments {
TemplateArgumentList *TemplateArgs;
unsigned CallArgIndex;
};
+
+ struct DFIParamWithArgumentsAndSuppliedType : DFIArguments {
+ TemplateParameter Param;
+ TemplateArgument SuppliedType;
+ };
// Structure used by DeductionFailureInfo to store information about
// unsatisfied constraints.
struct CNSInfo {
@@ -736,8 +742,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
TemplateDeductionResult TDK,
TemplateDeductionInfo &Info) {
DeductionFailureInfo Result;
+
Result.Result = static_cast<unsigned>(TDK);
Result.HasDiagnostic = false;
+
switch (TDK) {
case TemplateDeductionResult::Invalid:
case TemplateDeductionResult::InstantiationDepth:
@@ -749,10 +757,9 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
break;
case TemplateDeductionResult::Incomplete:
- case TemplateDeductionResult::InvalidExplicitArguments:
+ // case TemplateDeductionResult::InvalidExplicitArguments:
Result.Data = Info.Param.getOpaqueValue();
break;
-
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested: {
// FIXME: Should allocate from normal heap so that we can free this later.
@@ -777,6 +784,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
case TemplateDeductionResult::IncompletePack:
// FIXME: It's slightly wasteful to allocate two TemplateArguments for this.
case TemplateDeductionResult::Inconsistent:
+
case TemplateDeductionResult::Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
@@ -786,6 +794,16 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
Result.Data = Saved;
break;
}
+ case TemplateDeductionResult::InvalidExplicitArguments: {
+ DFIParamWithArgumentsAndSuppliedType *Saved =
+ new (Context) DFIParamWithArgumentsAndSuppliedType;
+ Saved->Param = Info.Param;
+ Saved->FirstArg = Info.FirstArg;
+ Saved->SecondArg = Info.SecondArg;
+ Saved->SuppliedType = Info.SuppliedType;
+ Result.Data = Saved;
+ break;
+ }
case TemplateDeductionResult::SubstitutionFailure:
Result.Data = Info.takeSugared();
@@ -822,13 +840,14 @@ void DeductionFailureInfo::Destroy() {
case TemplateDeductionResult::Incomplete:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
+ // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
break;
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested:
@@ -885,11 +904,11 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
return TemplateParameter();
case TemplateDeductionResult::Incomplete:
- case TemplateDeductionResult::InvalidExplicitArguments:
return TemplateParameter::getFromOpaqueValue(Data);
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
return static_cast<DFIParamWithArguments*>(Data)->Param;
@@ -938,6 +957,16 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
return nullptr;
}
+const TemplateArgument *DeductionFailureInfo::getSuppliedType() {
+ switch (static_cast<TemplateDeductionResult>(Result)) {
+ case TemplateDeductionResult::InvalidExplicitArguments:
+ return &static_cast<DFIParamWithArgumentsAndSuppliedType *>(Data)
+ ->SuppliedType;
+ default:
+ return nullptr;
+ }
+}
+
const TemplateArgument *DeductionFailureInfo::getFirstArg() {
switch (static_cast<TemplateDeductionResult>(Result)) {
case TemplateDeductionResult::Success:
@@ -946,15 +975,17 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {
case TemplateDeductionResult::Incomplete:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
+ // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::SubstitutionFailure:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return nullptr;
-
+ // case TemplateDeductionResult::InvalidExplicitArguments: //move back up
+ // there^^
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested:
@@ -979,7 +1010,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
+ // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::SubstitutionFailure:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
@@ -987,6 +1018,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
return nullptr;
case TemplateDeductionResult::Inconsistent:
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested:
@@ -11613,6 +11645,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
(ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
(ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
(ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
+
switch (DeductionFailure.getResult()) {
case TemplateDeductionResult::Success:
llvm_unreachable(
@@ -11716,11 +11749,14 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
case TemplateDeductionResult::InvalidExplicitArguments:
assert(ParamD && "no parameter found for invalid explicit arguments");
- if (ParamD->getDeclName())
+ if (ParamD->getDeclName()) {
+ auto FirstArg = *DeductionFailure.getFirstArg();
+ auto SecondArg = *DeductionFailure.getSecondArg();
+ auto SuppliedType = *DeductionFailure.getSuppliedType();
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
- << ParamD->getDeclName();
- else {
+ << FirstArg << SuppliedType << SecondArg;
+ } else {
int index = 0;
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
index = TTP->getIndex();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 1c1f6e30ab7b8..92415d49ee7a4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3575,7 +3575,15 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
unsigned Index = SugaredBuilder.size();
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
+
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
+ Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
+ Info.SecondArg = TemplateArgument(
+ dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index))
+ ->getType());
+ Info.SuppliedType = TemplateArgument(
+ ExplicitTemplateArgs[Index].getSourceExpression()->getType());
+
return TemplateDeductionResult::InvalidExplicitArguments;
}
>From e3a60c1f0adbf1801d51ab4d7834469349c0382a Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 14 Jan 2025 11:41:17 -0500
Subject: [PATCH 02/31] Improved safety, added some rt checks
---
clang/lib/Sema/SemaTemplateDeduction.cpp | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 92415d49ee7a4..521e0da3ef2f9 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -766,6 +766,12 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
+// Helper function to make template argument
+static TemplateArgument makeTemplateArgument(Decl *D) {
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
+ return TemplateArgument(NTTP->getType());
+ return TemplateArgument();
+}
/// A pack that we're currently deducing.
struct clang::DeducedPack {
@@ -3578,11 +3584,19 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
- Info.SecondArg = TemplateArgument(
- dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index))
- ->getType());
- Info.SuppliedType = TemplateArgument(
- ExplicitTemplateArgs[Index].getSourceExpression()->getType());
+ Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index));
+ // Info.SecondArg = TemplateArgument(
+ // dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index))
+ // ->getType());
+
+ // NonTypeTemplateParmDecl tmp =
+ // makeTemplateArgument(TemplateParams->getParam(Index)); if(!tmp.isNull()){
+ // Info.SecondArg = tmp->getType();
+ // }
+ if (ExplicitTemplateArgs[Index].getArgument().getKind() ==
+ TemplateArgument::Expression)
+ Info.SuppliedType = TemplateArgument(
+ ExplicitTemplateArgs[Index].getSourceExpression()->getType());
return TemplateDeductionResult::InvalidExplicitArguments;
}
>From 86d44be78faaac1439977ea0ae2f8a213ca28aa3 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 15 Jan 2025 16:51:10 -0500
Subject: [PATCH 03/31] Fixed error message formatting
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1456f34538bcc..0afba2ad68131 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4871,8 +4871,8 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
"%1 and %3 of conflicting types for parameter %0}2,4">;
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
- "template argument deduction/substitution failed:"
- "error: could not convert '%0' from %1 to %2">;
+ "candidate template ignored: invalid explicitly-specified argument "
+ "could not convert '%0' from %1 to %2">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
>From 9c1210d7a711a5324a10cba8af770028244cf34d Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 15:49:02 -0500
Subject: [PATCH 04/31] Update logic and tests
---
.../clang/Basic/DiagnosticSemaKinds.td | 18 ++-
clang/lib/Sema/SemaOverload.cpp | 133 ++++++++++++++++--
clang/lib/Sema/SemaTemplateDeduction.cpp | 46 ++++--
clang/test/CXX/drs/cwg2xx.cpp | 6 +-
clang/test/CXX/expr/expr.const/p3-0x.cpp | 2 +-
clang/test/SemaCXX/nullptr-98.cpp | 2 +-
.../test/SemaTemplate/overload-candidates.cpp | 4 +-
.../SemaTemplate/temp_arg_nontype_cxx11.cpp | 2 +-
8 files changed, 180 insertions(+), 33 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0afba2ad68131..a6110d14564e8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4870,9 +4870,25 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
"candidate template ignored: deduced values %diff{"
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
"%1 and %3 of conflicting types for parameter %0}2,4">;
+
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
- "could not convert '%0' from %1 to %2">;
+ "for template parameter %0: ">;
+
+def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
+ "candidate template ignored: invalid explicitly-specified argument "
+ "for template parameter %0: "
+ "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">;
+
+def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note<
+ "candidate template ignored: invalid explicitly-specified argument "
+ "for template parameter %0: "
+ "could not convert '%1' from %2 to %3">;
+def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note<
+ "candidate template ignored: invalid explicitly-specified argument "
+ "for template parameter %0: "
+ "expected constant of type %1 got type %2">;
+
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6c437a52be21d..e1e5bdd268ef4 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -902,7 +902,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return TemplateParameter();
-
+ // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Incomplete:
return TemplateParameter::getFromOpaqueValue(Data);
@@ -11641,10 +11641,27 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
unsigned NumArgs,
bool TakingCandidateAddress) {
TemplateParameter Param = DeductionFailure.getTemplateParameter();
+ int form;
NamedDecl *ParamD;
- (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
- (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
- (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
+ TemplateTypeParmDecl *TTPD;
+ NonTypeTemplateParmDecl *NTTPD;
+ TemplateTemplateParmDecl *TTempPD;
+ if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl *>())) {
+ llvm::dbgs() << "case 1" << '\n';
+ TTPD = cast<TemplateTypeParmDecl>(ParamD);
+ form = 1;
+ } else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>())) {
+ llvm::dbgs() << "case 2" << '\n';
+ NTTPD = cast<NonTypeTemplateParmDecl>(ParamD);
+ form = 2;
+ } else if ((ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>())) {
+ llvm::dbgs() << "case 3" << '\n';
+ TTempPD = cast<TemplateTemplateParmDecl>(ParamD);
+ form = 3;
+ } else {
+ llvm::dbgs() << "case 0" << '\n';
+ form = 0;
+ }
switch (DeductionFailure.getResult()) {
case TemplateDeductionResult::Success:
@@ -11747,15 +11764,108 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
return;
}
- case TemplateDeductionResult::InvalidExplicitArguments:
+ case TemplateDeductionResult::InvalidExplicitArguments: {
assert(ParamD && "no parameter found for invalid explicit arguments");
+
if (ParamD->getDeclName()) {
- auto FirstArg = *DeductionFailure.getFirstArg();
- auto SecondArg = *DeductionFailure.getSecondArg();
- auto SuppliedType = *DeductionFailure.getSuppliedType();
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named)
- << FirstArg << SuppliedType << SecondArg;
+ TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
+ std::string SecondArg = ParamD->getNameAsString();
+ TemplateArgument SuppliedType = *DeductionFailure.getSuppliedType();
+ // llvm::dbgs() << ParamD->getNameAsString() << '\n';
+ // llvm::dbgs() << ParamD->getDeclName().getAsString() << '\n';
+ // llvm::dbgs() << ParamD->getQualifiedNameAsString() << '\n';
+ // llvm::dbgs() << ParamD->getUnderlyingDecl()->getNameAsString() << '\n';
+ // llvm::dbgs() << NTTPD->getType() << '\n';
+ // llvm::dbgs() << '\n';
+ // FirstArg.dump();
+ // llvm::dbgs() << '\n';
+ // SuppliedType.dump();
+ // llvm::dbgs() << '\n';
+ // llvm::dbgs() << SecondArg << '\n';
+ switch (form) {
+
+ // TemplateTypeParmDecl
+ case 1: {
+ // could not convert '42' from 'int' to TypeParam T
+ assert(TTPD);
+ TTPD->dump();
+ if (TTPD->wasDeclaredWithTypename())
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
+ << ParamD->getDeclName() << FirstArg << SuppliedType << SecondArg
+ << "type";
+ else {
+ // TODO write tests for type constrained classes
+ if (auto *constraint = TTPD->getTypeConstraint())
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
+ << ParamD->getDeclName() << FirstArg << SuppliedType
+ << SecondArg << "valid type-constrained class";
+ else
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
+ << ParamD->getDeclName() << FirstArg << SuppliedType
+ << SecondArg << "class";
+ }
+ break;
+ }
+ // NonTypeTemplateParmDecl
+ case 2: {
+ assert(NTTPD);
+ if (SuppliedType.isNull()) {
+ // Expected constant of type 'int', got type 'int'
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp)
+ << ParamD->getDeclName() << FirstArg << NTTPD->getType();
+ } else {
+ // Could not convert A from B to C
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp)
+ << ParamD->getDeclName() << FirstArg << SuppliedType
+ << NTTPD->getType();
+ }
+ break;
+ }
+ case 3: {
+ assert(TTempPD);
+ // FirstArg.dump();
+ // llvm::dbgs() << SecondArg << '\n' << SuppliedType.isNull() << '\n';
+ // llvm::dbgs() << TTempPD->getDefaultArgument().getTypeSourceInfo() <<
+ // '\n';
+
+ // expected a template of type 'template<class> class T', got
+ // 'template<class T1, class T2> struct InvalidTemplate'
+
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ << ParamD->getDeclName();
+ break;
+ }
+ default:
+ llvm_unreachable("unexpected case");
+ }
+
+ // auto SecondArg = *DeductionFailure.getSecondArg();
+
+ // S.Diag(Templated->getLocation(),
+ // diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ // << FirstArg << SuppliedType << SecondArg;
+ // if(SecondArg.isNull()){
+ // S.Diag(Templated->getLocation(),
+ // diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ // << FirstArg << SuppliedType << ParamD->getDeclName();
+ // }
+ // else if(SuppliedType.isNull()){
+ // S.Diag(Templated->getLocation(),
+ // diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ // << FirstArg << "SuppliedTypeNull" << SecondArg;
+ // }
+ // else{
+ // S.Diag(Templated->getLocation(),
+ // diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ // << FirstArg << SuppliedType << SecondArg;
+ // }
+
} else {
int index = 0;
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
@@ -11771,6 +11881,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
}
MaybeEmitInheritedConstructorNote(S, Found);
return;
+ }
case TemplateDeductionResult::ConstraintsNotSatisfied: {
// Format the template argument list into the argument string.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 521e0da3ef2f9..d36d8b7fb250f 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -768,8 +768,12 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
}
// Helper function to make template argument
static TemplateArgument makeTemplateArgument(Decl *D) {
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
+ D)) // I in template<int I, typename T>
return TemplateArgument(NTTP->getType());
+ // if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D)) // T in
+ // template<int I, typename T>
+ // return TemplateArgument(TTP);
return TemplateArgument();
}
@@ -3582,21 +3586,37 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
+ /*
+
+ template<int I, typename T> //TemplateParams
+ void get(const T&);
+
+ void test_get(void *ptr) {
+ get<int>(ptr); //TemplateArgs
+ }
+ */
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index));
- // Info.SecondArg = TemplateArgument(
- // dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(Index))
- // ->getType());
-
- // NonTypeTemplateParmDecl tmp =
- // makeTemplateArgument(TemplateParams->getParam(Index)); if(!tmp.isNull()){
- // Info.SecondArg = tmp->getType();
- // }
- if (ExplicitTemplateArgs[Index].getArgument().getKind() ==
- TemplateArgument::Expression)
- Info.SuppliedType = TemplateArgument(
- ExplicitTemplateArgs[Index].getSourceExpression()->getType());
+ // FunctionTemplate->dump();
+ // Info.SuppliedType = makeTemplateArgument(TemplateParams->getParam(1));
+ // llvm::dbgs() << TemplateParams->getParam(1) << '\n' <<
+ // TemplateParams->getParam(1)->getNameAsString(); llvm::dbgs() <<
+ // TemplateParams->size() << ExplicitTemplateArgs.size() <<
+ // ParamTypes.size() << Deduced.size() << DeducedArgs.size() << "\n";
+
+ switch (ExplicitTemplateArgs[Index].getArgument().getKind()) {
+ case TemplateArgument::Expression:
+ Info.SuppliedType =
+ ExplicitTemplateArgs[Index].getSourceExpression()->getType();
+ break;
+ case TemplateArgument::Type:
+ Info.SuppliedType =
+ TemplateArgument(); // ExplicitTemplateArgs[Index].getArgument();
+ break;
+ default:
+ break;
+ }
return TemplateDeductionResult::InvalidExplicitArguments;
}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 0d644bae78382..08180c70faad6 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9
A::g<3>(b);
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
using C::f;
using C::g;
f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T'}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
// expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
g<3>(b);
}
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index 5bd70c5250b59..c8e96ef963e5f 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -105,7 +105,7 @@ void c() {
break;
}
}
-template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}}
+template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B': could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}}
template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
template int f<(bool)&S::operator int>();
diff --git a/clang/test/SemaCXX/nullptr-98.cpp b/clang/test/SemaCXX/nullptr-98.cpp
index 306b2033e4568..fbbceb90d1d9f 100644
--- a/clang/test/SemaCXX/nullptr-98.cpp
+++ b/clang/test/SemaCXX/nullptr-98.cpp
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
// expected-no-diagnostics
void f(void *);
-void g() { f(__nullptr); }
+void g() { f(__nullptr); }
\ No newline at end of file
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index de998d74f9af6..abfd896a611ba 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -17,7 +17,7 @@ void test_dyn_cast(int* ptr) {
}
template<int I, typename T>
- void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' got type 'int'}}
template<template<class T> class, typename T>
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
@@ -163,4 +163,4 @@ namespace PR15673 {
CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)>
void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}}
void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}}
-}
+}
\ No newline at end of file
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 5752cbac0291d..50ae078867534 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -43,7 +43,7 @@ void TempFunc() {}
void Useage() {
//expected-error at +2 {{no matching function}}
- //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b'}}
+ //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b': could not convert '-1' from 'int' to 'unsigned int'}}
TempFunc<1, -1, 1>();
}
}
>From 4aca9d7247380f945757044aeddd906a04d75f6e Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 18:55:31 -0500
Subject: [PATCH 05/31] Cleaned up code, removed suppliedType
---
clang/include/clang/Sema/TemplateDeduction.h | 5 -
clang/lib/Sema/SemaOverload.cpp | 134 +++----------------
clang/lib/Sema/SemaTemplateDeduction.cpp | 42 +-----
3 files changed, 23 insertions(+), 158 deletions(-)
diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h
index 9edd3724cf53c..28b014fd84e4b 100644
--- a/clang/include/clang/Sema/TemplateDeduction.h
+++ b/clang/include/clang/Sema/TemplateDeduction.h
@@ -250,9 +250,6 @@ class TemplateDeductionInfo {
/// \brief The constraint satisfaction details resulting from the associated
/// constraints satisfaction tests.
ConstraintSatisfaction AssociatedConstraintsSatisfaction;
-
- /// \brief Type supplied by user for deduction
- TemplateArgument SuppliedType;
};
} // namespace sema
@@ -303,8 +300,6 @@ struct DeductionFailureInfo {
TemplateDeductionResult getResult() const {
return static_cast<TemplateDeductionResult>(Result);
}
-
- const TemplateArgument *getSuppliedType();
};
/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index e1e5bdd268ef4..e1fed0e9c9e9e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -723,10 +723,6 @@ namespace {
unsigned CallArgIndex;
};
- struct DFIParamWithArgumentsAndSuppliedType : DFIArguments {
- TemplateParameter Param;
- TemplateArgument SuppliedType;
- };
// Structure used by DeductionFailureInfo to store information about
// unsatisfied constraints.
struct CNSInfo {
@@ -795,12 +791,10 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
break;
}
case TemplateDeductionResult::InvalidExplicitArguments: {
- DFIParamWithArgumentsAndSuppliedType *Saved =
- new (Context) DFIParamWithArgumentsAndSuppliedType;
+ DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
Saved->Param = Info.Param;
Saved->FirstArg = Info.FirstArg;
Saved->SecondArg = Info.SecondArg;
- Saved->SuppliedType = Info.SuppliedType;
Result.Data = Saved;
break;
}
@@ -902,10 +896,8 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return TemplateParameter();
- // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Incomplete:
return TemplateParameter::getFromOpaqueValue(Data);
-
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
@@ -937,7 +929,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
return nullptr;
-
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested:
return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs;
@@ -957,16 +948,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
return nullptr;
}
-const TemplateArgument *DeductionFailureInfo::getSuppliedType() {
- switch (static_cast<TemplateDeductionResult>(Result)) {
- case TemplateDeductionResult::InvalidExplicitArguments:
- return &static_cast<DFIParamWithArgumentsAndSuppliedType *>(Data)
- ->SuppliedType;
- default:
- return nullptr;
- }
-}
-
const TemplateArgument *DeductionFailureInfo::getFirstArg() {
switch (static_cast<TemplateDeductionResult>(Result)) {
case TemplateDeductionResult::Success:
@@ -975,14 +956,11 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {
case TemplateDeductionResult::Incomplete:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::SubstitutionFailure:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return nullptr;
- // case TemplateDeductionResult::InvalidExplicitArguments: //move back up
- // there^^
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
@@ -1010,13 +988,11 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::SubstitutionFailure:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return nullptr;
-
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
@@ -11641,27 +11617,11 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
unsigned NumArgs,
bool TakingCandidateAddress) {
TemplateParameter Param = DeductionFailure.getTemplateParameter();
- int form;
NamedDecl *ParamD;
- TemplateTypeParmDecl *TTPD;
- NonTypeTemplateParmDecl *NTTPD;
- TemplateTemplateParmDecl *TTempPD;
- if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl *>())) {
- llvm::dbgs() << "case 1" << '\n';
- TTPD = cast<TemplateTypeParmDecl>(ParamD);
- form = 1;
- } else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>())) {
- llvm::dbgs() << "case 2" << '\n';
- NTTPD = cast<NonTypeTemplateParmDecl>(ParamD);
- form = 2;
- } else if ((ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>())) {
- llvm::dbgs() << "case 3" << '\n';
- TTempPD = cast<TemplateTemplateParmDecl>(ParamD);
- form = 3;
- } else {
- llvm::dbgs() << "case 0" << '\n';
- form = 0;
- }
+
+ (ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) ||
+ (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) ||
+ (ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>());
switch (DeductionFailure.getResult()) {
case TemplateDeductionResult::Success:
@@ -11769,50 +11729,30 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
if (ParamD->getDeclName()) {
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
- std::string SecondArg = ParamD->getNameAsString();
- TemplateArgument SuppliedType = *DeductionFailure.getSuppliedType();
- // llvm::dbgs() << ParamD->getNameAsString() << '\n';
- // llvm::dbgs() << ParamD->getDeclName().getAsString() << '\n';
- // llvm::dbgs() << ParamD->getQualifiedNameAsString() << '\n';
- // llvm::dbgs() << ParamD->getUnderlyingDecl()->getNameAsString() << '\n';
- // llvm::dbgs() << NTTPD->getType() << '\n';
- // llvm::dbgs() << '\n';
- // FirstArg.dump();
- // llvm::dbgs() << '\n';
- // SuppliedType.dump();
- // llvm::dbgs() << '\n';
- // llvm::dbgs() << SecondArg << '\n';
- switch (form) {
-
- // TemplateTypeParmDecl
- case 1: {
- // could not convert '42' from 'int' to TypeParam T
- assert(TTPD);
- TTPD->dump();
+ std::string ParamName = ParamD->getNameAsString();
+ TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
+
+ if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
if (TTPD->wasDeclaredWithTypename())
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SuppliedType << SecondArg
+ << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
<< "type";
else {
// TODO write tests for type constrained classes
if (auto *constraint = TTPD->getTypeConstraint())
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SuppliedType
- << SecondArg << "valid type-constrained class";
+ << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
+ << "valid type-constrained class";
else
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SuppliedType
- << SecondArg << "class";
+ << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
+ << "class";
}
- break;
- }
- // NonTypeTemplateParmDecl
- case 2: {
- assert(NTTPD);
- if (SuppliedType.isNull()) {
+ } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
+ if (SecondArg.isNull()) {
// Expected constant of type 'int', got type 'int'
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp)
@@ -11821,51 +11761,15 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
// Could not convert A from B to C
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp)
- << ParamD->getDeclName() << FirstArg << SuppliedType
+ << ParamD->getDeclName() << FirstArg << SecondArg
<< NTTPD->getType();
}
- break;
- }
- case 3: {
- assert(TTempPD);
- // FirstArg.dump();
- // llvm::dbgs() << SecondArg << '\n' << SuppliedType.isNull() << '\n';
- // llvm::dbgs() << TTempPD->getDefaultArgument().getTypeSourceInfo() <<
- // '\n';
-
- // expected a template of type 'template<class> class T', got
- // 'template<class T1, class T2> struct InvalidTemplate'
-
+ } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
<< ParamD->getDeclName();
- break;
- }
- default:
+ } else
llvm_unreachable("unexpected case");
- }
-
- // auto SecondArg = *DeductionFailure.getSecondArg();
-
- // S.Diag(Templated->getLocation(),
- // diag::note_ovl_candidate_explicit_arg_mismatch_named)
- // << FirstArg << SuppliedType << SecondArg;
- // if(SecondArg.isNull()){
- // S.Diag(Templated->getLocation(),
- // diag::note_ovl_candidate_explicit_arg_mismatch_named)
- // << FirstArg << SuppliedType << ParamD->getDeclName();
- // }
- // else if(SuppliedType.isNull()){
- // S.Diag(Templated->getLocation(),
- // diag::note_ovl_candidate_explicit_arg_mismatch_named)
- // << FirstArg << "SuppliedTypeNull" << SecondArg;
- // }
- // else{
- // S.Diag(Templated->getLocation(),
- // diag::note_ovl_candidate_explicit_arg_mismatch_named)
- // << FirstArg << SuppliedType << SecondArg;
- // }
-
} else {
int index = 0;
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index d36d8b7fb250f..806da4ba240c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -766,16 +766,6 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
-// Helper function to make template argument
-static TemplateArgument makeTemplateArgument(Decl *D) {
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
- D)) // I in template<int I, typename T>
- return TemplateArgument(NTTP->getType());
- // if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D)) // T in
- // template<int I, typename T>
- // return TemplateArgument(TTP);
- return TemplateArgument();
-}
/// A pack that we're currently deducing.
struct clang::DeducedPack {
@@ -3586,37 +3576,13 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
- /*
-
- template<int I, typename T> //TemplateParams
- void get(const T&);
-
- void test_get(void *ptr) {
- get<int>(ptr); //TemplateArgs
- }
- */
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
- Info.SecondArg = makeTemplateArgument(TemplateParams->getParam(Index));
- // FunctionTemplate->dump();
- // Info.SuppliedType = makeTemplateArgument(TemplateParams->getParam(1));
- // llvm::dbgs() << TemplateParams->getParam(1) << '\n' <<
- // TemplateParams->getParam(1)->getNameAsString(); llvm::dbgs() <<
- // TemplateParams->size() << ExplicitTemplateArgs.size() <<
- // ParamTypes.size() << Deduced.size() << DeducedArgs.size() << "\n";
-
- switch (ExplicitTemplateArgs[Index].getArgument().getKind()) {
- case TemplateArgument::Expression:
- Info.SuppliedType =
+ Info.SecondArg = TemplateArgument();
+ if (ExplicitTemplateArgs[Index].getArgument().getKind() ==
+ TemplateArgument::Expression)
+ Info.SecondArg =
ExplicitTemplateArgs[Index].getSourceExpression()->getType();
- break;
- case TemplateArgument::Type:
- Info.SuppliedType =
- TemplateArgument(); // ExplicitTemplateArgs[Index].getArgument();
- break;
- default:
- break;
- }
return TemplateDeductionResult::InvalidExplicitArguments;
}
>From 9c10aa953002243cf9ffbb9f99fd0ec94e503169 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 18:58:39 -0500
Subject: [PATCH 06/31] removed newlines diagnosticSemKinds.td
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ----
1 file changed, 4 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a6110d14564e8..ea1013f7ef7b7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4870,16 +4870,13 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
"candidate template ignored: deduced values %diff{"
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
"%1 and %3 of conflicting types for parameter %0}2,4">;
-
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: ">;
-
def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
"could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">;
-
def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
@@ -4888,7 +4885,6 @@ def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
"expected constant of type %1 got type %2">;
-
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
>From 35d79a7e6224684f9d6e81b839ac0ab1947cfc4e Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <47676355+AidanGoldfarb at users.noreply.github.com>
Date: Mon, 20 Jan 2025 19:03:00 -0500
Subject: [PATCH 07/31] Update clang/lib/Sema/SemaOverload.cpp
Co-authored-by: Justin Fargnoli <jfargnoli at nvidia.com>
---
clang/lib/Sema/SemaOverload.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index e1fed0e9c9e9e..61564ed4f1ca2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11618,7 +11618,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
bool TakingCandidateAddress) {
TemplateParameter Param = DeductionFailure.getTemplateParameter();
NamedDecl *ParamD;
-
(ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) ||
(ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) ||
(ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>());
>From babe495ac378a49440b1fa2de80b0cea4d026b3e Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <47676355+AidanGoldfarb at users.noreply.github.com>
Date: Mon, 20 Jan 2025 19:03:10 -0500
Subject: [PATCH 08/31] Update clang/lib/Sema/SemaOverload.cpp
Co-authored-by: Justin Fargnoli <jfargnoli at nvidia.com>
---
clang/lib/Sema/SemaOverload.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 61564ed4f1ca2..63b63c85d1d84 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11725,7 +11725,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
case TemplateDeductionResult::InvalidExplicitArguments: {
assert(ParamD && "no parameter found for invalid explicit arguments");
-
if (ParamD->getDeclName()) {
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
std::string ParamName = ParamD->getNameAsString();
>From 7984368fbf47884f378bb6af80c03b3dc5a495c1 Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <47676355+AidanGoldfarb at users.noreply.github.com>
Date: Mon, 20 Jan 2025 19:03:33 -0500
Subject: [PATCH 09/31] Update clang/test/SemaCXX/nullptr-98.cpp
Co-authored-by: Justin Fargnoli <jfargnoli at nvidia.com>
---
clang/test/SemaCXX/nullptr-98.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/SemaCXX/nullptr-98.cpp b/clang/test/SemaCXX/nullptr-98.cpp
index fbbceb90d1d9f..306b2033e4568 100644
--- a/clang/test/SemaCXX/nullptr-98.cpp
+++ b/clang/test/SemaCXX/nullptr-98.cpp
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
// expected-no-diagnostics
void f(void *);
-void g() { f(__nullptr); }
\ No newline at end of file
+void g() { f(__nullptr); }
>From 13607304b7a608a01e39de1d5ad8abba27d1a752 Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <47676355+AidanGoldfarb at users.noreply.github.com>
Date: Mon, 20 Jan 2025 19:04:40 -0500
Subject: [PATCH 10/31] Apply suggestions from code review
Co-authored-by: Justin Fargnoli <jfargnoli at nvidia.com>
---
clang/lib/Sema/SemaOverload.cpp | 3 ---
clang/lib/Sema/SemaTemplateDeduction.cpp | 1 -
clang/test/SemaTemplate/overload-candidates.cpp | 2 +-
3 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 63b63c85d1d84..aa64f631dbe44 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -753,7 +753,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
break;
case TemplateDeductionResult::Incomplete:
- // case TemplateDeductionResult::InvalidExplicitArguments:
Result.Data = Info.Param.getOpaqueValue();
break;
case TemplateDeductionResult::DeducedMismatch:
@@ -780,7 +779,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
case TemplateDeductionResult::IncompletePack:
// FIXME: It's slightly wasteful to allocate two TemplateArguments for this.
case TemplateDeductionResult::Inconsistent:
-
case TemplateDeductionResult::Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
@@ -834,7 +832,6 @@ void DeductionFailureInfo::Destroy() {
case TemplateDeductionResult::Incomplete:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- // case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
break;
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 806da4ba240c4..18f82ef0b936a 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3575,7 +3575,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
unsigned Index = SugaredBuilder.size();
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
-
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
Info.SecondArg = TemplateArgument();
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index abfd896a611ba..bc181c7942402 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -163,4 +163,4 @@ namespace PR15673 {
CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)>
void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}}
void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}}
-}
\ No newline at end of file
+}
>From ffdc1b6fce146748107a7828f0f02920e68c163b Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 19:10:10 -0500
Subject: [PATCH 11/31] some newlines removed
---
clang/lib/Sema/SemaOverload.cpp | 4 ----
1 file changed, 4 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index aa64f631dbe44..5400f4cdcfc93 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -715,14 +715,12 @@ namespace {
struct DFIParamWithArguments : DFIArguments {
TemplateParameter Param;
};
-
// Structure used by DeductionFailureInfo to store template argument
// information and the index of the problematic call argument.
struct DFIDeducedMismatchArgs : DFIArguments {
TemplateArgumentList *TemplateArgs;
unsigned CallArgIndex;
};
-
// Structure used by DeductionFailureInfo to store information about
// unsatisfied constraints.
struct CNSInfo {
@@ -738,10 +736,8 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
TemplateDeductionResult TDK,
TemplateDeductionInfo &Info) {
DeductionFailureInfo Result;
-
Result.Result = static_cast<unsigned>(TDK);
Result.HasDiagnostic = false;
-
switch (TDK) {
case TemplateDeductionResult::Invalid:
case TemplateDeductionResult::InstantiationDepth:
>From b22f2390fe2bbde7daab9cd72ceb73d20be265a6 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 19:12:41 -0500
Subject: [PATCH 12/31] some newlines added
---
clang/lib/Sema/SemaOverload.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5400f4cdcfc93..13be184267c1c 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -889,8 +889,10 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return TemplateParameter();
+
case TemplateDeductionResult::Incomplete:
return TemplateParameter::getFromOpaqueValue(Data);
+
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
@@ -922,6 +924,7 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
return nullptr;
+
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested:
return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs;
@@ -954,6 +957,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return nullptr;
+
case TemplateDeductionResult::IncompletePack:
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
@@ -986,6 +990,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
case TemplateDeductionResult::NonDependentConversionFailure:
case TemplateDeductionResult::ConstraintsNotSatisfied:
return nullptr;
+
case TemplateDeductionResult::Inconsistent:
case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::Underqualified:
>From 170825651d8bf1897f592e21b5ab9a2ab488b033 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 20 Jan 2025 19:15:14 -0500
Subject: [PATCH 13/31] a newline added
---
clang/lib/Sema/SemaOverload.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 13be184267c1c..6c14535176886 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -751,6 +751,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
case TemplateDeductionResult::Incomplete:
Result.Data = Info.Param.getOpaqueValue();
break;
+
case TemplateDeductionResult::DeducedMismatch:
case TemplateDeductionResult::DeducedMismatchNested: {
// FIXME: Should allocate from normal heap so that we can free this later.
>From 256d22b0cf7c81279030b1f3da936efc29824298 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 21 Jan 2025 10:38:46 -0500
Subject: [PATCH 14/31] more cleanup
---
clang/lib/Sema/SemaOverload.cpp | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6c14535176886..856b2fe5c7b4b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -773,6 +773,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
break;
}
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::IncompletePack:
// FIXME: It's slightly wasteful to allocate two TemplateArguments for this.
case TemplateDeductionResult::Inconsistent:
@@ -785,14 +786,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
Result.Data = Saved;
break;
}
- case TemplateDeductionResult::InvalidExplicitArguments: {
- DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
- Saved->Param = Info.Param;
- Saved->FirstArg = Info.FirstArg;
- Saved->SecondArg = Info.SecondArg;
- Result.Data = Saved;
- break;
- }
case TemplateDeductionResult::SubstitutionFailure:
Result.Data = Info.takeSugared();
>From 8a7ce10e282af2104c78635a4d1cd1f7c7ff72b4 Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <agoldfa7 at u.rochester.edu>
Date: Wed, 22 Jan 2025 14:59:54 -0500
Subject: [PATCH 15/31] Apply suggestions from code review
Co-authored-by: Justin Fargnoli <jfargnoli at nvidia.com>
---
clang/lib/Sema/SemaOverload.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 856b2fe5c7b4b..559d4c26b7fdc 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11610,10 +11610,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
bool TakingCandidateAddress) {
TemplateParameter Param = DeductionFailure.getTemplateParameter();
NamedDecl *ParamD;
- (ParamD = Param.dyn_cast<TemplateTypeParmDecl *>()) ||
- (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl *>()) ||
- (ParamD = Param.dyn_cast<TemplateTemplateParmDecl *>());
-
+ (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
+ (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
+ (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
switch (DeductionFailure.getResult()) {
case TemplateDeductionResult::Success:
llvm_unreachable(
>From 29491ec15180f650fabc6d2a7a79aa5dc625d6ad Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 22 Jan 2025 18:58:51 -0500
Subject: [PATCH 16/31] remove unneeded diag
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++--
clang/lib/Sema/SemaOverload.cpp | 13 +++++--------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ea1013f7ef7b7..a30caebc8fb2f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4877,11 +4877,11 @@ def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
"could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">;
-def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp : Note<
+def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
"could not convert '%1' from %2 to %3">;
-def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp : Note<
+def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
"expected constant of type %1 got type %2">;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 559d4c26b7fdc..ef6d820ed6a6b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11728,12 +11728,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
<< ParamD->getDeclName() << FirstArg << SecondArg << ParamName
<< "type";
else {
- // TODO write tests for type constrained classes
- if (auto *constraint = TTPD->getTypeConstraint())
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
- << "valid type-constrained class";
+ if (TTPD->getTypeConstraint())
+ llvm_unreachable("ill-formed program");
else
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
@@ -11744,16 +11740,17 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
if (SecondArg.isNull()) {
// Expected constant of type 'int', got type 'int'
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp)
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a)
<< ParamD->getDeclName() << FirstArg << NTTPD->getType();
} else {
// Could not convert A from B to C
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp)
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b)
<< ParamD->getDeclName() << FirstArg << SecondArg
<< NTTPD->getType();
}
} else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
+ TTempPD->dump();
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
<< ParamD->getDeclName();
>From 11fb7499e762bde2fb7fc792cd11256401028b3a Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Fri, 24 Jan 2025 13:32:18 -0500
Subject: [PATCH 17/31] cleaned up code
---
.../clang/Basic/DiagnosticSemaKinds.td | 4 ++--
clang/lib/Sema/SemaOverload.cpp | 21 +++++++++----------
clang/lib/Sema/SemaTemplateDeduction.cpp | 1 -
3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a30caebc8fb2f..3016677fc33a7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4870,9 +4870,9 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
"candidate template ignored: deduced values %diff{"
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
"%1 and %3 of conflicting types for parameter %0}2,4">;
-def note_ovl_candidate_explicit_arg_mismatch_named : Note<
+def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note<
"candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0: ">;
+ "for template parameter %0">;
def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ef6d820ed6a6b..f8987306fac78 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11728,31 +11728,30 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
<< ParamD->getDeclName() << FirstArg << SecondArg << ParamName
<< "type";
else {
- if (TTPD->getTypeConstraint())
- llvm_unreachable("ill-formed program");
- else
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
- << "class";
+ // Concept satisfied but not modeled => ill-formed
+ assert(!TTPD->getTypeConstraint() &&
+ "Concept satisfied but not modeled");
+
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
+ << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
+ << "class";
}
} else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
if (SecondArg.isNull()) {
- // Expected constant of type 'int', got type 'int'
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a)
<< ParamD->getDeclName() << FirstArg << NTTPD->getType();
} else {
- // Could not convert A from B to C
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b)
<< ParamD->getDeclName() << FirstArg << SecondArg
<< NTTPD->getType();
}
} else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
- TTempPD->dump();
+ // FIXME: Emit a better message here
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_temptemppd)
<< ParamD->getDeclName();
} else
llvm_unreachable("unexpected case");
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 18f82ef0b936a..74e9c45b4e8c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3577,7 +3577,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
return TemplateDeductionResult::SubstitutionFailure;
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
Info.FirstArg = ExplicitTemplateArgs[Index].getArgument();
- Info.SecondArg = TemplateArgument();
if (ExplicitTemplateArgs[Index].getArgument().getKind() ==
TemplateArgument::Expression)
Info.SecondArg =
>From 2acdb18a3c1b93f893d94a6c473473923d6c76cb Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 28 Jan 2025 15:03:15 -0500
Subject: [PATCH 18/31] simplified ttpd case and updated test
---
.../include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/SemaOverload.cpp | 18 +++---------------
clang/test/CXX/drs/cwg2xx.cpp | 6 +++---
3 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3016677fc33a7..b80e67a4b8f07 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4876,7 +4876,7 @@ def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note<
def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
- "could not convert '%1' from %2 to %4 '%3' (expected a %4, but got '%1')">;
+ "expectd a type, but got value '%1' (of type %2)">;
def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f8987306fac78..82fa00ca014f7 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11722,21 +11722,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
- if (TTPD->wasDeclaredWithTypename())
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
- << "type";
- else {
- // Concept satisfied but not modeled => ill-formed
- assert(!TTPD->getTypeConstraint() &&
- "Concept satisfied but not modeled");
-
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SecondArg << ParamName
- << "class";
- }
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
+ << ParamD->getDeclName() << FirstArg << SecondArg;
} else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
if (SecondArg.isNull()) {
S.Diag(Templated->getLocation(),
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 08180c70faad6..28fb9d86d4ff9 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9
A::g<3>(b);
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
using C::f;
using C::g;
f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': could not convert '3' from 'int' to class 'T' (expected a class, but got '3')}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
// expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
g<3>(b);
}
>From b36ff68a3f1404052080c3c0066c1c6a78ca924d Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <agoldfa7 at u.rochester.edu>
Date: Tue, 28 Jan 2025 15:24:19 -0500
Subject: [PATCH 19/31] Fixed type
Co-authored-by: Matheus Izvekov <mizvekov at gmail.com>
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b80e67a4b8f07..b0d1298d09532 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4876,7 +4876,7 @@ def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note<
def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
- "expectd a type, but got value '%1' (of type %2)">;
+ "expected a type, but got value '%1' (of type %2)">;
def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0: "
>From 6db7a7a98d0c378efa89cc33a5bde6ba74103522 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 28 Jan 2025 15:25:46 -0500
Subject: [PATCH 20/31] typo fixed
---
clang/test/CXX/drs/cwg2xx.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 28fb9d86d4ff9..2373b769b9172 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -649,15 +649,15 @@ namespace cwg241 { // cwg241: 9
A::g<3>(b);
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}}
using C::f;
using C::g;
f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expectd a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}}
// expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
g<3>(b);
}
>From fc7fec12efc2a1cf951922fa6f49a572a6021295 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 28 Jan 2025 20:49:39 -0500
Subject: [PATCH 21/31] merged diag defs into one
---
.../clang/Basic/DiagnosticSemaKinds.td | 20 ++++++-------------
clang/lib/Sema/SemaOverload.cpp | 17 ++++++++--------
.../test/SemaTemplate/overload-candidates.cpp | 2 +-
3 files changed, 16 insertions(+), 23 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b0d1298d09532..19af6eb6c6aaf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4870,21 +4870,13 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
"candidate template ignored: deduced values %diff{"
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
"%1 and %3 of conflicting types for parameter %0}2,4">;
-def note_ovl_candidate_explicit_arg_mismatch_named_temptemppd : Note<
+def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0">;
-def note_ovl_candidate_explicit_arg_mismatch_named_ttpd : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0: "
- "expected a type, but got value '%1' (of type %2)">;
-def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0: "
- "could not convert '%1' from %2 to %3">;
-def note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0: "
- "expected constant of type %1 got type %2">;
+ "for template parameter %1%select{"
+ "|: expected a type, but got value '%2' (of type %3)"
+ "|: could not convert '%2' from %3 to %4"
+ "|: expected constant of type %2 but got type %3"
+ "|}0">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 82fa00ca014f7..486e050aede16 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11723,24 +11723,25 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd)
- << ParamD->getDeclName() << FirstArg << SecondArg;
+ diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ << 1 << ParamD->getDeclName() << FirstArg << SecondArg;
+
} else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
if (SecondArg.isNull()) {
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_a)
- << ParamD->getDeclName() << FirstArg << NTTPD->getType();
+ diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ << 3 << ParamD->getDeclName() << NTTPD->getType() << FirstArg;
} else {
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_b)
- << ParamD->getDeclName() << FirstArg << SecondArg
+ diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ << 2 << ParamD->getDeclName() << FirstArg << SecondArg
<< NTTPD->getType();
}
} else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
// FIXME: Emit a better message here
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_named_temptemppd)
- << ParamD->getDeclName();
+ diag::note_ovl_candidate_explicit_arg_mismatch_named)
+ << 4 << ParamD->getDeclName();
} else
llvm_unreachable("unexpected case");
} else {
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index bc181c7942402..98ed02d8e9293 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -17,7 +17,7 @@ void test_dyn_cast(int* ptr) {
}
template<int I, typename T>
- void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' got type 'int'}}
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' but got type 'int'}}
template<template<class T> class, typename T>
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
>From b578b870dd6d65a945b63a84fcd5c93c1ee0daba Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <agoldfa7 at u.rochester.edu>
Date: Wed, 29 Jan 2025 10:29:07 -0500
Subject: [PATCH 22/31] Apply suggestions from code review
Co-authored-by: Matheus Izvekov <mizvekov at gmail.com>
---
clang/lib/Sema/SemaOverload.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 486e050aede16..5b2f7734f81c2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11718,7 +11718,6 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
assert(ParamD && "no parameter found for invalid explicit arguments");
if (ParamD->getDeclName()) {
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
- std::string ParamName = ParamD->getNameAsString();
TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
@@ -11743,7 +11742,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
diag::note_ovl_candidate_explicit_arg_mismatch_named)
<< 4 << ParamD->getDeclName();
} else
- llvm_unreachable("unexpected case");
+ llvm_unreachable("unexpected param decl kind");
} else {
int index = 0;
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
>From 340627d442e7bf221463ad5a66845006d1a68cef Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 29 Jan 2025 14:18:37 -0500
Subject: [PATCH 23/31] reverted caret change, pipped sourceRange instead
---
clang/lib/Sema/SemaOverload.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5b2f7734f81c2..a386dcdf25355 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11723,24 +11723,26 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
- << 1 << ParamD->getDeclName() << FirstArg << SecondArg;
+ << 1 << ParamD->getDeclName() << FirstArg << SecondArg
+ << TTPD->getSourceRange();
} else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
if (SecondArg.isNull()) {
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
- << 3 << ParamD->getDeclName() << NTTPD->getType() << FirstArg;
+ << 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->getType() << NTTPD->getSourceRange();
}
} else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
// FIXME: Emit a better message here
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
- << 4 << ParamD->getDeclName();
+ << 4 << ParamD->getDeclName() << TTempPD->getSourceRange();
} else
llvm_unreachable("unexpected param decl kind");
} else {
>From 64584bc2650f8e1f42f3c8e7a8e2b664880b78a7 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Thu, 30 Jan 2025 12:12:51 -0500
Subject: [PATCH 24/31] refactor. split diag into two notes, updated tests.
---
.../clang/Basic/DiagnosticSemaKinds.td | 16 ++---
clang/lib/Sema/SemaOverload.cpp | 71 ++++++++-----------
clang/test/CXX/drs/cwg2xx.cpp | 9 ++-
clang/test/CXX/expr/expr.const/p3-0x.cpp | 4 +-
.../test/SemaTemplate/overload-candidates.cpp | 4 +-
.../SemaTemplate/temp_arg_nontype_cxx11.cpp | 5 +-
6 files changed, 53 insertions(+), 56 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 19af6eb6c6aaf..0c533b76e3b5c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4870,18 +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 %1%select{"
- "|: expected a type, but got value '%2' (of type %3)"
- "|: could not convert '%2' from %3 to %4"
- "|: expected constant of type %2 but got type %3"
- "|}0">;
+ "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">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
-def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for %ordinal0 template parameter">;
def note_ovl_candidate_instantiation_depth : Note<
"candidate template ignored: substitution exceeded maximum template "
"instantiation depth">;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a386dcdf25355..5d050da63570d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11716,48 +11716,39 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
case TemplateDeductionResult::InvalidExplicitArguments: {
assert(ParamD && "no parameter found for invalid explicit arguments");
- if (ParamD->getDeclName()) {
- TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
- TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
-
- if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(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<NonTypeTemplateParmDecl>(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<TemplateTemplateParmDecl>(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;
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
- index = TTP->getIndex();
- else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(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<TemplateTypeParmDecl>(ParamD)) {
+ Which = 1;
+ Index = TTPD->getIndex();
+ SrcRange = TTPD->getSourceRange();
+ } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
+ if (SecondArg.isNull())
+ Which = 2;
else
- index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
+ Which = 3;
+ Index = NTTPD->getIndex();
+ Type = NTTPD->getType();
+ SrcRange = NTTPD->getSourceRange();
+ } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
+ Which = 4;
+ Index = TTempPD->getIndex();
+ SrcRange = TTempPD->getSourceRange();
+ } else
+ llvm_unreachable("unexpected param decl kind");
+
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch)
+ << (Index + 1) << SrcRange;
+ if (ParamD->getDeclName() && Which != 4)
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
- << (index + 1);
- }
+ diag::note_ovl_candidate_explicit_arg_mismatch_detail)
+ << Which << FirstArg << SecondArg << Type;
MaybeEmitInheritedConstructorNote(S, Found);
return;
}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 2373b769b9172..b7e72df9d1ee3 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -649,15 +649,18 @@ namespace cwg241 { // cwg241: 9
A::g<3>(b);
C::f<3>(b);
// expected-error at -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 a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#cwg241-C-f {{expected a type, but got value '3'}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for template parameter 'T': expected a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#cwg241-C-g {{expected a type, but got value '3'}}
using C::f;
using C::g;
f<3>(b);
// expected-error at -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 a type, but got value '3' (of type 'int')}}
+ // expected-note@#cwg241-C-f {{andidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#cwg241-C-f {{expected a type, but got value '3'}}
// expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
g<3>(b);
}
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index c8e96ef963e5f..cc96c93920330 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -105,7 +105,9 @@ void c() {
break;
}
}
-template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B': could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}}
+template <bool B> int f() { return B; } // #f-bool-int
+// expected-note@#f-bool-int {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+// expected-note@#f-bool-int {{could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}}
template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
template int f<(bool)&S::operator int>();
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index 98ed02d8e9293..fa3598b807102 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -17,7 +17,9 @@ void test_dyn_cast(int* ptr) {
}
template<int I, typename T>
- void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I': expected constant of type 'int' but got type 'int'}}
+ void get(const T&); // #get-int-typename
+ // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#get-int-typename {{expected constant of type 'int' but got type 'int'}}
template<template<class T> class, typename T>
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 50ae078867534..e470802aee64b 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -42,8 +42,9 @@ template <int a, unsigned b, int c>
void TempFunc() {}
void Useage() {
- //expected-error at +2 {{no matching function}}
- //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b': could not convert '-1' from 'int' to 'unsigned int'}}
+ //expected-error at +3 {{no matching function}}
+ //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for 2nd template parameter}}
+ //expected-note at -5 {{could not convert '-1' from 'int' to 'unsigned int'}}
TempFunc<1, -1, 1>();
}
}
>From 1468562a02661632b928a08a48acaf6951e3af4a Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 4 Feb 2025 12:19:37 -0500
Subject: [PATCH 25/31] const expr hack
---
.../clang/Basic/DiagnosticSemaKinds.td | 10 +--
clang/lib/AST/ExprConstant.cpp | 13 +++-
clang/lib/Sema/SemaOverload.cpp | 65 ++++++++++---------
clang/lib/Sema/SemaTemplateDeduction.cpp | 4 ++
clang/test/AST/ByteCode/builtin-align-cxx.cpp | 4 +-
clang/test/AST/ByteCode/cxx20.cpp | 4 +-
.../basic.namespace/namespace.udecl/p12.cpp | 8 +--
clang/test/CXX/temp/temp.param/p8-cxx20.cpp | 16 ++---
clang/test/SemaCXX/builtin-align-cxx.cpp | 4 +-
clang/test/SemaCXX/calling-conv-compat.cpp | 5 +-
.../constexpr-function-recovery-crash.cpp | 2 +-
clang/test/SemaCXX/cxx2a-template-lambdas.cpp | 3 +-
clang/test/SemaCXX/typo-correction.cpp | 2 +-
clang/test/SemaTemplate/cwg2398.cpp | 3 +-
14 files changed, 82 insertions(+), 61 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0c533b76e3b5c..2006bf667e748 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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 : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for %ordinal0 template parameter">;
+
def note_ovl_candidate_explicit_arg_mismatch_detail : Note<
+ "candidate template ignored: invalid explicitly-specified argument"
"%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">;
+ "|: could not convert '%1' from %2 to %3"
+ "| for %ordinal4 template parameter"
+ "|: expr is not a valid const expr in the expected context}0">;
+
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_instantiation_depth : Note<
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2e680d1569f60..8530f4ccb06a1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16814,8 +16814,17 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
(!EvaluateDestruction(Ctx, Base, Result.Val, T, getBeginLoc(), Result,
true) ||
Result.HasSideEffects)) {
- // FIXME: Prefix a note to indicate that the problem is lack of constant
- // destruction.
+
+ // FIXME: err_constexpr_var_requires_const_destruction?
+ PartialDiagnostic PD(diag::err_constexpr_var_requires_const_destruction,
+ const_cast<ASTContext &>(Ctx).getDiagAllocator());
+ std::string ExprStr;
+ llvm::raw_string_ostream OS(ExprStr);
+ this->printPretty(OS, nullptr, PrintingPolicy(Ctx.getLangOpts()));
+ PD << ExprStr;
+ SourceLocation Loc = this->getBeginLoc();
+ Result.Diag->insert(Result.Diag->begin(), PartialDiagnosticAt(Loc, PD));
+
return false;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5d050da63570d..3964656ffda0a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11716,39 +11716,46 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
case TemplateDeductionResult::InvalidExplicitArguments: {
assert(ParamD && "no parameter found for invalid explicit arguments");
- int Which = 0;
- int Index = 0;
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
- QualType Type;
- SourceRange SrcRange;
-
- if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ParamD)) {
- Which = 1;
- Index = TTPD->getIndex();
- SrcRange = TTPD->getSourceRange();
- } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ParamD)) {
- if (SecondArg.isNull())
- Which = 2;
- else
- Which = 3;
- Index = NTTPD->getIndex();
- Type = NTTPD->getType();
- SrcRange = NTTPD->getSourceRange();
- } else if (auto *TTempPD = dyn_cast<TemplateTemplateParmDecl>(ParamD)) {
- Which = 4;
- Index = TTempPD->getIndex();
- SrcRange = TTempPD->getSourceRange();
- } else
- llvm_unreachable("unexpected param decl kind");
+ auto TupleResult = [&]() -> std::tuple<int, int, QualType> {
+ switch (ParamD->getKind()) {
+ case Decl::TemplateTypeParm: {
+ auto *TTPD = cast<TemplateTypeParmDecl>(ParamD);
+ return {1, TTPD->getIndex(), QualType()};
+ }
+ case Decl::NonTypeTemplateParm: {
+ auto *NTTPD = cast<NonTypeTemplateParmDecl>(ParamD);
+ if (SecondArg.isNull())
+ return {2, NTTPD->getIndex(), NTTPD->getType()};
+ else {
+ // FIXME: this is a hack, we should do this in SemaTempalteDeduction
+ // or even ExprConstant. Perhaps an InvalidExplicitArguments error
+ // is not what we want
+ QualType qt = NTTPD->getType();
+ if (qt.getCanonicalType() !=
+ SecondArg.getAsType().getCanonicalType()) {
+ return {3, NTTPD->getIndex(), NTTPD->getType()};
+ } else {
+ return {5, NTTPD->getIndex(), NTTPD->getType()};
+ }
+ }
+ }
+ case Decl::TemplateTemplateParm: {
+ auto *TTempPD = cast<TemplateTemplateParmDecl>(ParamD);
+ return {4, TTempPD->getIndex(), QualType()};
+ }
+ default:
+ llvm_unreachable("unexpected param decl kind");
+ }
+ };
+ auto [Which, Index, Type] = TupleResult();
+ S.NoteTemplateParameterLocation(*ParamD);
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch)
- << (Index + 1) << SrcRange;
- if (ParamD->getDeclName() && Which != 4)
- S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_detail)
- << Which << FirstArg << SecondArg << Type;
+ diag::note_ovl_candidate_explicit_arg_mismatch_detail)
+ << Which << FirstArg << SecondArg << Type << (Index + 1);
+
MaybeEmitInheritedConstructorNote(S, Found);
return;
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 74e9c45b4e8c4..10abe58b0c944 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3572,6 +3572,10 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
SugaredBuilder, CanonicalBuilder,
/*UpdateArgsWithConversions=*/false) ||
Trap.hasErrorOccurred()) {
+
+ // FIXME: decide if ill formed const expr or regular
+ // InvalidExplicitArguments?
+
unsigned Index = SugaredBuilder.size();
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
diff --git a/clang/test/AST/ByteCode/builtin-align-cxx.cpp b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
index a1edf307d6c47..7a554f55af49c 100644
--- a/clang/test/AST/ByteCode/builtin-align-cxx.cpp
+++ b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
@@ -3,8 +3,8 @@
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -std=c++11 %s -fsyntax-only -verify=ref,both
// Check that we don't crash when using dependent types in __builtin_align:
-template <typename a, a b>
-void *c(void *d) { // both-note{{candidate template ignored}}
+template <typename a, a b> // both-note{{template parameter is declared here}}
+void *c(void *d) { // both-note{{candidate template ignored: invalid explicitly-specified argument: could not convert 'foo' from 'x' to 'a'}}
return __builtin_align_down(d, b);
}
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index 268362ceff635..4581ea08faaab 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -750,8 +750,8 @@ namespace FailingDestructor {
throw "oh no";
}
};
- template<D d>
- void f() {} // both-note {{invalid explicitly-specified argument}}
+ template<D d> // both-note{{template parameter is declared here}}
+ void f() {} // both-note{{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
void g() {
f<D{0, false}>(); // both-error {{no matching function}}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index f12e0083fb0c9..53f395e060e4e 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -113,21 +113,21 @@ namespace test3 {
struct Derived1 : Base {
using Base::foo;
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
};
struct Derived2 : Base {
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
using Base::foo;
};
struct Derived3 : Base {
using Base::foo;
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '0'}}
};
struct Derived4 : Base {
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '0'}}
using Base::foo;
};
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index a3478c0669661..a5f9614422f3c 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -35,12 +35,12 @@ namespace ConstDestruction {
constexpr ~D() {
if (!can_destroy)
- throw "oh no"; // expected-note {{subexpression not valid}}
+ throw "oh no";
}
};
- template<D d>
- void f() {} // expected-note 2{{invalid explicitly-specified argument}}
+ template<D d> // expected-note 2{{template parameter is declared here}}
+ void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
void g() {
f<D{0, true}>();
@@ -48,18 +48,14 @@ namespace ConstDestruction {
}
// We can SFINAE on constant destruction.
- template<typename T> auto h(T t) -> decltype(f<T{1, false}>());
- template<typename T> auto h(T t) -> decltype(f<T{1, true}>());
+ // template<typename T> auto h(T t) -> decltype(f<T{1, false}>());
+ // template<typename T> auto h(T t) -> decltype(f<T{1, true}>());
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<D{1, false}>(); // expected-error {{no matching function}}
f<D{1, true}>();
}
-
- template<D d> struct Z {};
- Z<D{2, true}> z1;
- Z<D{2, false}> z2; // expected-error {{non-type template argument is not a constant expression}} expected-note-re {{in call to '{{.*}}.~D()'}}
}
diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp b/clang/test/SemaCXX/builtin-align-cxx.cpp
index d18bc2bf66551..2392e94141ab2 100644
--- a/clang/test/SemaCXX/builtin-align-cxx.cpp
+++ b/clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -std=c++11 -o - %s -fsyntax-only -verify
// Check that we don't crash when using dependent types in __builtin_align:
-template <typename a, a b>
-void *c(void *d) { // expected-note{{candidate template ignored}}
+template <typename a, a b> // expected-note{{template parameter is declared here}}
+void *c(void *d) { // expected-note{{candidate template ignored: invalid explicitly-specified argument: could not convert 'foo' from 'x' to 'a'}}
return __builtin_align_down(d, b);
}
diff --git a/clang/test/SemaCXX/calling-conv-compat.cpp b/clang/test/SemaCXX/calling-conv-compat.cpp
index 5a51e34b1478c..fcb2eafea73c9 100644
--- a/clang/test/SemaCXX/calling-conv-compat.cpp
+++ b/clang/test/SemaCXX/calling-conv-compat.cpp
@@ -424,7 +424,8 @@ namespace D50526 {
template<typename T, T (__stdcall f)()> void g();
void h() { g<void, h>(); }
#if !_M_X64
- // expected-error at -2 {{no matching function for call to}}
- // expected-note at -4 {{invalid explicitly-specified argument}}
+ // expected-note at -3 {{template parameter is declared here}}
+ // expected-error at -3 {{no matching function for call to}}
+ // expected-note at -5 {{candidate template ignored: invalid explicitly-specified argument: could not convert 'h' from 'void ()' to 'T (*)() __attribute__((stdcall))}}
#endif
}
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index 90ee7892b2fc2..542967aa952fc 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,7 +60,7 @@ constexpr void test8() {
throw "bad";
}
-template<int x> constexpr int f(int y) { // expected-note {{candidate template ignored}}
+template<int x> constexpr int f(int y) { //expected-note {{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
return x * y;
}
constexpr int test9(int x) {
diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
index 00ba291fbd198..b4389b7183a6d 100644
--- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
@@ -45,7 +45,8 @@ template<typename T>
constexpr T outer() {
// FIXME: The C++11 error seems wrong
return []<T x>() { return x; }.template operator()<123>(); // expected-error {{no matching member function}} \
- expected-note {{candidate template ignored}} \
+ expected-note {{template parameter is declared here}} \
+ expected-note {{candidate template ignored: invalid explicitly-specified argument: could not convert '123' from 'int' to 'int *'}} \
cxx11-note {{non-literal type '<dependent type>' cannot be used in a constant expression}} \
cxx14-note {{non-literal type}}
}
diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp
index 45f42c4260358..ef1fa9b18479d 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -613,7 +613,7 @@ int bar() {
}
namespace testIncludeTypeInTemplateArgument {
-template <typename T, typename U>
+template <typename T, typename U> // expected-note {{template parameter is declared here}}
void foo(T t = {}, U = {}); // expected-note {{candidate template ignored}}
class AddObservation {}; // expected-note {{declared here}}
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 6dc7af6ea1789..5a041a13679e9 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -138,7 +138,8 @@ namespace ttp_defaults {
template <template <class T2> class TT2> void f(A<TT2>);
// new-note at -1 {{explicit instantiation candidate}}
- // old-note at -2 {{invalid explicitly-specified argument for template parameter 'TT2'}}
+ // old-note at -2 {{template parameter is declared here}}
+ // old-note at -3 {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
// FIXME: The default arguments on the TTP are not available during partial ordering.
template <template <class T3, class T4 = float> class TT3> void f(A<TT3>) {};
>From 6c4804193d1951d1dd4fa52642d114c2d13ffa0d Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 4 Feb 2025 14:16:11 -0500
Subject: [PATCH 26/31] revert tests, will be changed later. One should still
fail
---
clang/test/CXX/drs/cwg2xx.cpp | 19 ++++++++++---------
clang/test/CXX/drs/cwg3xx.cpp | 6 ++++--
clang/test/CXX/expr/expr.const/p3-0x.cpp | 4 ++--
.../test/CXX/temp/temp.res/temp.local/p1.cpp | 4 ++--
clang/test/Modules/cxx-templates.cpp | 2 ++
.../test/SemaTemplate/overload-candidates.cpp | 9 ++++-----
.../SemaTemplate/temp_arg_nontype_cxx11.cpp | 4 ++--
7 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index b7e72df9d1ee3..c74096cc9383d 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -645,23 +645,23 @@ namespace cwg241 { // cwg241: 9
// cxx98-17-error at -1 {{use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension}}
A::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
+ // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
A::g<3>(b);
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
- // expected-note@#cwg241-C-f {{expected a type, but got value '3'}}
+ // expected-note@#cwg241-C-f 2{{template parameter is declared here}}
+ // expected-note@#cwg241-C-f 2{{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '3}}
+
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
- // expected-note@#cwg241-C-g {{expected a type, but got value '3'}}
+ // expected-note@#cwg241-C-g {{template parameter is declared here}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '3}}
+
using C::f;
using C::g;
f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
- // expected-note@#cwg241-C-f {{andidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
- // expected-note@#cwg241-C-f {{expected a type, but got value '3'}}
- // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
+ // expected-note@#cwg241-A-f {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
g<3>(b);
}
} // namespace cwg241
@@ -954,7 +954,8 @@ namespace cwg258 { // cwg258: 2.8
int &w = b.f(0);
int &x = b.g<int>(0);
// expected-error at -1 {{no matching member function for call to 'g'}}
- // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#cwg258-B-g {{template parameter is declared here}}
+ // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
int &y = b.h();
float &z = const_cast<const B&>(b).h();
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index b5e07a66bb4ed..634f9bf35d36a 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -981,8 +981,10 @@ namespace cwg354 { // cwg354: 3.1 c++11
int b0 = both<0>();
int b1 = both<(int*)0>();
// cxx98-error at -1 {{no matching function for call to 'both'}}
- // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
- // cxx98-note@#cwg354-both-int {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // cxx98-note@#cwg354-both-int-ptr {{template parameter is declared here}}
+ // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument: could not convert '(int *)0' from 'int *' to 'int'}}
+ // cxx98-note@#cwg354-both-int {{template parameter is declared here}}
+ // cxx98-note@#cwg354-both-int {{candidate template ignored: invalid explicitly-specified argument: could not convert '(int *)0' from 'int *' to 'int'}}
template<int S::*> struct ptr_mem {}; // #cwg354-ptr_mem
ptr_mem<0> m0; // #cwg354-m0
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index cc96c93920330..6e54acb44e2d4 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -106,8 +106,8 @@ void c() {
}
}
template <bool B> int f() { return B; } // #f-bool-int
-// expected-note@#f-bool-int {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
-// expected-note@#f-bool-int {{could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}}
+// expected-note@#f-bool-int {{template parameter is declared here}}
+// expected-note@#f-bool-int {{candidate template ignored: invalid explicitly-specified argument: could not convert '&S::operator int' from 'int (S::*)() const' to 'bool'}}
template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
template int f<(bool)&S::operator int>();
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
index faa85cb5fce30..16c8ca05f39b3 100644
--- a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -10,9 +10,9 @@ template<typename> char id;
template<typename> struct TempType {};
template<template<typename> class> struct TempTemp {};
-template<typename> void use(int&); // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}}
+template<typename> void use(int&); // expected-note{{template parameter is declared here}} // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}}
template<template<typename> class> void use(float&); // expected-note 2{{no known conversion}}
-template<int> void use(char&); // expected-note 2{{invalid explicitly-specified argument}}
+template<int> void use(char&); // expected-note 2{{template parameter is declared here}} // expected-note 2{{invalid explicitly-specified argument}}
template<typename T> struct A {
template<typename> struct C {};
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index 7b41a0b0bfb2c..88ac89226e7f1 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -42,10 +42,12 @@ void g() {
template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function}}
+ // expected-note at Inputs/cxx-templates-a.h:11 {{template parameter is declared here}}
// expected-note at Inputs/cxx-templates-a.h:11 {{invalid explicitly-specified argument}}
// expected-note at Inputs/cxx-templates-b.h:11 {{invalid explicitly-specified argument}}
template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
+ // expected-note at Inputs/cxx-templates-b.h:11 {{template parameter is declared here}}
// expected-note at Inputs/cxx-templates-a.h:11 {{candidate}}
// expected-note at Inputs/cxx-templates-b.h:11 {{candidate}}
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index fa3598b807102..9d8a6932f6dfc 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -16,12 +16,11 @@ void test_dyn_cast(int* ptr) {
(void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
}
-template<int I, typename T>
+template<int I, typename T> // expected-note {{template parameter is declared here}}
void get(const T&); // #get-int-typename
- // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
- // expected-note@#get-int-typename {{expected constant of type 'int' but got type 'int'}}
-template<template<class T> class, typename T>
- void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
+template<template<class T> class, typename T> // expected-note {{template parameter is declared here}}
+ void get(const T&); // expected-note {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
void test_get(void *ptr) {
get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index e470802aee64b..343d168d2560c 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -43,8 +43,8 @@ void TempFunc() {}
void Useage() {
//expected-error at +3 {{no matching function}}
- //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for 2nd template parameter}}
- //expected-note at -5 {{could not convert '-1' from 'int' to 'unsigned int'}}
+ //expected-note at -5 {{template parameter is declared here}}
+ //expected-note at -5 {{candidate template ignored: invalid explicitly-specified argument: could not convert '-1' from 'int' to 'unsigned int'}}
TempFunc<1, -1, 1>();
}
}
>From 199dc79be3ea064ad00b1be8397ef168be2f685f Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 5 Feb 2025 11:02:13 -0500
Subject: [PATCH 27/31] revert hack/tests. Next commit will clean up error
messages
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +--
clang/lib/AST/ExprConstant.cpp | 13 ++-----------
clang/lib/Sema/SemaOverload.cpp | 14 +++++++-------
clang/lib/Sema/SemaTemplateDeduction.cpp | 3 ---
clang/test/AST/ByteCode/cxx20.cpp | 2 +-
clang/test/CXX/drs/cwg3xx.cpp | 2 +-
clang/test/CXX/temp/temp.param/p8-cxx20.cpp | 2 +-
.../SemaCXX/constexpr-function-recovery-crash.cpp | 2 +-
8 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2006bf667e748..1fa73c761f379 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4877,8 +4877,7 @@ def note_ovl_candidate_explicit_arg_mismatch_detail : Note<
"|: expected a type, but got value '%1'"
"|: expected constant of type %3 but got type %1"
"|: could not convert '%1' from %2 to %3"
- "| for %ordinal4 template parameter"
- "|: expr is not a valid const expr in the expected context}0">;
+ "| for %ordinal4 template parameter}0">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8530f4ccb06a1..2e680d1569f60 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16814,17 +16814,8 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
(!EvaluateDestruction(Ctx, Base, Result.Val, T, getBeginLoc(), Result,
true) ||
Result.HasSideEffects)) {
-
- // FIXME: err_constexpr_var_requires_const_destruction?
- PartialDiagnostic PD(diag::err_constexpr_var_requires_const_destruction,
- const_cast<ASTContext &>(Ctx).getDiagAllocator());
- std::string ExprStr;
- llvm::raw_string_ostream OS(ExprStr);
- this->printPretty(OS, nullptr, PrintingPolicy(Ctx.getLangOpts()));
- PD << ExprStr;
- SourceLocation Loc = this->getBeginLoc();
- Result.Diag->insert(Result.Diag->begin(), PartialDiagnosticAt(Loc, PD));
-
+ // FIXME: Prefix a note to indicate that the problem is lack of constant
+ // destruction.
return false;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 3964656ffda0a..899331f151b7a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11730,15 +11730,15 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
if (SecondArg.isNull())
return {2, NTTPD->getIndex(), NTTPD->getType()};
else {
- // FIXME: this is a hack, we should do this in SemaTempalteDeduction
- // or even ExprConstant. Perhaps an InvalidExplicitArguments error
- // is not what we want
+ // 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, NTTPD->getIndex(), NTTPD->getType()};
+ if (qt.getCanonicalType() ==
+ SecondArg.getAsType().getCanonicalType() &&
+ __cplusplus <= 201703) {
+ return {4, NTTPD->getIndex(), NTTPD->getType()};
} else {
- return {5, NTTPD->getIndex(), NTTPD->getType()};
+ return {3, NTTPD->getIndex(), NTTPD->getType()};
}
}
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 10abe58b0c944..48b4febce89ba 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3573,9 +3573,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
/*UpdateArgsWithConversions=*/false) ||
Trap.hasErrorOccurred()) {
- // FIXME: decide if ill formed const expr or regular
- // InvalidExplicitArguments?
-
unsigned Index = SugaredBuilder.size();
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index 4581ea08faaab..dfff819bf84d5 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -751,7 +751,7 @@ namespace FailingDestructor {
}
};
template<D d> // both-note{{template parameter is declared here}}
- void f() {} // both-note{{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
+ void f() {} // both-note{{andidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
void g() {
f<D{0, false}>(); // both-error {{no matching function}}
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 634f9bf35d36a..bf91f745ecb0f 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -982,7 +982,7 @@ namespace cwg354 { // cwg354: 3.1 c++11
int b1 = both<(int*)0>();
// cxx98-error at -1 {{no matching function for call to 'both'}}
// cxx98-note@#cwg354-both-int-ptr {{template parameter is declared here}}
- // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument: could not convert '(int *)0' from 'int *' to 'int'}}
+ // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
// cxx98-note@#cwg354-both-int {{template parameter is declared here}}
// cxx98-note@#cwg354-both-int {{candidate template ignored: invalid explicitly-specified argument: could not convert '(int *)0' from 'int *' to 'int'}}
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index a5f9614422f3c..48cf1c874eb2f 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -40,7 +40,7 @@ namespace ConstDestruction {
};
template<D d> // expected-note 2{{template parameter is declared here}}
- void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
+ void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
void g() {
f<D{0, true}>();
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index 542967aa952fc..34e0d01c150dc 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,7 +60,7 @@ constexpr void test8() {
throw "bad";
}
-template<int x> constexpr int f(int y) { //expected-note {{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expr is not a valid const expr in the expected context}}
+template<int x> constexpr int f(int y) { //expected-note {{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
return x * y;
}
constexpr int test9(int x) {
>From 9bdaa17fb536d1a6dbb5fc7e320622f87cd02958 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 5 Feb 2025 14:45:18 -0500
Subject: [PATCH 28/31] simplified diagnostics
---
.../clang/Basic/DiagnosticSemaKinds.td | 10 ++++----
clang/lib/Sema/SemaOverload.cpp | 23 ++++++++++---------
.../basic.namespace/namespace.udecl/p12.cpp | 8 +++----
clang/test/CXX/drs/cwg2xx.cpp | 6 ++---
.../test/SemaTemplate/overload-candidates.cpp | 2 +-
5 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1fa73c761f379..990223cfb79f8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4871,13 +4871,13 @@ 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_detail : Note<
+def note_ovl_candidate_explicit_arg_mismatch : Note<
"candidate template ignored: invalid explicitly-specified argument"
"%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"
- "| for %ordinal4 template parameter}0">;
+ "|: %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">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 899331f151b7a..313d2a8d3072d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11719,42 +11719,43 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
- auto TupleResult = [&]() -> std::tuple<int, int, QualType> {
+ auto TupleResult = [&]() -> std::tuple<int, int, int, int, QualType> {
switch (ParamD->getKind()) {
case Decl::TemplateTypeParm: {
auto *TTPD = cast<TemplateTypeParmDecl>(ParamD);
- return {1, TTPD->getIndex(), QualType()};
+ return {1, 0, 1, TTPD->getIndex(), QualType()};
}
case Decl::NonTypeTemplateParm: {
auto *NTTPD = cast<NonTypeTemplateParmDecl>(ParamD);
- if (SecondArg.isNull())
- return {2, NTTPD->getIndex(), NTTPD->getType()};
- else {
+ 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() &&
__cplusplus <= 201703) {
- return {4, NTTPD->getIndex(), NTTPD->getType()};
+ return {3, -1, -1, NTTPD->getIndex(), NTTPD->getType()};
} else {
- return {3, NTTPD->getIndex(), NTTPD->getType()};
+ return {2, -1, -1, NTTPD->getIndex(), NTTPD->getType()};
}
}
}
case Decl::TemplateTemplateParm: {
auto *TTempPD = cast<TemplateTemplateParmDecl>(ParamD);
- return {4, TTempPD->getIndex(), QualType()};
+ return {3, -1, -1, TTempPD->getIndex(), QualType()};
}
default:
llvm_unreachable("unexpected param decl kind");
}
};
- auto [Which, Index, Type] = TupleResult();
+ auto [Which, Provided, Expected, Index, Type] = TupleResult();
S.NoteTemplateParameterLocation(*ParamD);
S.Diag(Templated->getLocation(),
- diag::note_ovl_candidate_explicit_arg_mismatch_detail)
- << Which << FirstArg << SecondArg << Type << (Index + 1);
+ diag::note_ovl_candidate_explicit_arg_mismatch)
+ << Which << Provided << Expected << FirstArg << SecondArg << Type
+ << (Index + 1);
MaybeEmitInheritedConstructorNote(S, Found);
return;
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index 53f395e060e4e..70fc61a3b2b34 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -113,21 +113,21 @@ namespace test3 {
struct Derived1 : Base {
using Base::foo;
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
};
struct Derived2 : Base {
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
using Base::foo;
};
struct Derived3 : Base {
using Base::foo;
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '0'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible with type parameter 'int'}}
};
struct Derived4 : Base {
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '0'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{andidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible with type parameter 'int'}}
using Base::foo;
};
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index c74096cc9383d..33b1d0b4a645e 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -650,12 +650,12 @@ namespace cwg241 { // cwg241: 9
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
// expected-note@#cwg241-C-f 2{{template parameter is declared here}}
- // expected-note@#cwg241-C-f 2{{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '3}}
+ // expected-note@#cwg241-C-f 2{{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible with type parameter 'int'}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
// expected-note@#cwg241-C-g {{template parameter is declared here}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument: expected a type, but got value '3}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible with type parameter 'int'}}
using C::f;
using C::g;
@@ -955,7 +955,7 @@ namespace cwg258 { // cwg258: 2.8
int &x = b.g<int>(0);
// expected-error at -1 {{no matching member function for call to 'g'}}
// expected-note@#cwg258-B-g {{template parameter is declared here}}
- // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
+ // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
int &y = b.h();
float &z = const_cast<const B&>(b).h();
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index 9d8a6932f6dfc..9356892b81956 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -18,7 +18,7 @@ void test_dyn_cast(int* ptr) {
template<int I, typename T> // expected-note {{template parameter is declared here}}
void get(const T&); // #get-int-typename
- // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument: expected constant of type 'int' but got type 'int'}}
+ // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
template<template<class T> class, typename T> // expected-note {{template parameter is declared here}}
void get(const T&); // expected-note {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
>From 748cd352d0303427ebbd06a75cb110f2ffd95764 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 5 Feb 2025 15:21:51 -0500
Subject: [PATCH 29/31] removed unneeded (and incorrect) std version check
---
clang/lib/Sema/SemaOverload.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 313d2a8d3072d..ceacbed3b135e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11734,8 +11734,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
// for ill-formed const exprs in >=C++20.
QualType qt = NTTPD->getType();
if (qt.getCanonicalType() ==
- SecondArg.getAsType().getCanonicalType() &&
- __cplusplus <= 201703) {
+ SecondArg.getAsType().getCanonicalType()) {
return {3, -1, -1, NTTPD->getIndex(), NTTPD->getType()};
} else {
return {2, -1, -1, NTTPD->getIndex(), NTTPD->getType()};
>From 237bb0ecf39666f4f4fc5b23d24f0752ea47f4ac Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 25 Feb 2025 10:48:15 -0500
Subject: [PATCH 30/31] further simplified diagnostics, updated tests
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 ++---
clang/lib/Sema/SemaOverload.cpp | 11 +++++------
.../dcl.dcl/basic.namespace/namespace.udecl/p12.cpp | 8 ++++----
clang/test/CXX/drs/cwg2xx.cpp | 6 +++---
clang/test/CXX/drs/cwg3xx.cpp | 2 +-
clang/test/CXX/temp/temp.param/p8-cxx20.cpp | 2 +-
.../SemaCXX/constexpr-function-recovery-crash.cpp | 2 +-
clang/test/SemaTemplate/cwg2398.cpp | 2 +-
clang/test/SemaTemplate/overload-candidates.cpp | 4 ++--
9 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 990223cfb79f8..6f0caa8898e53 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4874,10 +4874,9 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
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"
+ "|: %select{non-type|type|template}1 argument %select{'%3'|%3|%3}1 is not compatible"
"|: could not convert '%3' from %4 to %5"
- "| for %ordinal6 template parameter}0">;
+ "|}0">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ceacbed3b135e..3acc2b34a4ffa 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11719,7 +11719,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
TemplateArgument FirstArg = *DeductionFailure.getFirstArg();
TemplateArgument SecondArg = *DeductionFailure.getSecondArg();
- auto TupleResult = [&]() -> std::tuple<int, int, int, int, QualType> {
+ auto [Which, Provided, Expected, Index,
+ Type] = [&]() -> std::tuple<int, int, int, int, QualType> {
switch (ParamD->getKind()) {
case Decl::TemplateTypeParm: {
auto *TTPD = cast<TemplateTypeParmDecl>(ParamD);
@@ -11743,19 +11744,17 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
}
case Decl::TemplateTemplateParm: {
auto *TTempPD = cast<TemplateTemplateParmDecl>(ParamD);
- return {3, -1, -1, TTempPD->getIndex(), QualType()};
+ return {1, 2, -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);
-
+ S.NoteTemplateParameterLocation(*ParamD);
MaybeEmitInheritedConstructorNote(S, Found);
return;
}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index 70fc61a3b2b34..d839703b58875 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -113,21 +113,21 @@ namespace test3 {
struct Derived1 : Base {
using Base::foo;
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible}}
};
struct Derived2 : Base {
- template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible}}
using Base::foo;
};
struct Derived3 : Base {
using Base::foo;
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible with type parameter 'int'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible}}
};
struct Derived4 : Base {
- template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{andidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible with type parameter 'int'}}
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note{{template parameter is declared here}} // expected-note {{andidate template ignored: invalid explicitly-specified argument: non-type argument '0' is not compatible}}
using Base::foo;
};
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 33b1d0b4a645e..1d40d7185276e 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -650,12 +650,12 @@ namespace cwg241 { // cwg241: 9
C::f<3>(b);
// expected-error at -1 {{no matching function for call to 'f'}}
// expected-note@#cwg241-C-f 2{{template parameter is declared here}}
- // expected-note@#cwg241-C-f 2{{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible with type parameter 'int'}}
+ // expected-note@#cwg241-C-f 2{{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible}}
C::g<3>(b);
// expected-error at -1 {{no matching function for call to 'g'}}
// expected-note@#cwg241-C-g {{template parameter is declared here}}
- // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible with type parameter 'int'}}
+ // expected-note@#cwg241-C-g {{candidate template ignored: invalid explicitly-specified argument: non-type argument '3' is not compatible}}
using C::f;
using C::g;
@@ -955,7 +955,7 @@ namespace cwg258 { // cwg258: 2.8
int &x = b.g<int>(0);
// expected-error at -1 {{no matching member function for call to 'g'}}
// expected-note@#cwg258-B-g {{template parameter is declared here}}
- // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
+ // expected-note@#cwg258-B-g {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible}}
int &y = b.h();
float &z = const_cast<const B&>(b).h();
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index bf91f745ecb0f..4f21398f9de3b 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -982,7 +982,7 @@ namespace cwg354 { // cwg354: 3.1 c++11
int b1 = both<(int*)0>();
// cxx98-error at -1 {{no matching function for call to 'both'}}
// cxx98-note@#cwg354-both-int-ptr {{template parameter is declared here}}
- // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument}}
// cxx98-note@#cwg354-both-int {{template parameter is declared here}}
// cxx98-note@#cwg354-both-int {{candidate template ignored: invalid explicitly-specified argument: could not convert '(int *)0' from 'int *' to 'int'}}
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index 48cf1c874eb2f..921ac3361f3de 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -40,7 +40,7 @@ namespace ConstDestruction {
};
template<D d> // expected-note 2{{template parameter is declared here}}
- void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ void f() {} // expected-note 2{{candidate template ignored: invalid explicitly-specified argument}}
void g() {
f<D{0, true}>();
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index 34e0d01c150dc..2ac21b3668be6 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,7 +60,7 @@ constexpr void test8() {
throw "bad";
}
-template<int x> constexpr int f(int y) { //expected-note {{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+template<int x> constexpr int f(int y) { //expected-note {{template parameter is declared here}} // expected-note {{candidate template ignored: invalid explicitly-specified argument}}
return x * y;
}
constexpr int test9(int x) {
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 5a041a13679e9..db1ce6be2981f 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -139,7 +139,7 @@ namespace ttp_defaults {
template <template <class T2> class TT2> void f(A<TT2>);
// new-note at -1 {{explicit instantiation candidate}}
// old-note at -2 {{template parameter is declared here}}
- // old-note at -3 {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // old-note at -3 {{candidate template ignored: invalid explicitly-specified argument}}
// FIXME: The default arguments on the TTP are not available during partial ordering.
template <template <class T3, class T4 = float> class TT3> void f(A<TT3>) {};
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index 9356892b81956..29d36af210e51 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -18,9 +18,9 @@ void test_dyn_cast(int* ptr) {
template<int I, typename T> // expected-note {{template parameter is declared here}}
void get(const T&); // #get-int-typename
- // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible with non-type parameter 'int'}}
+ // expected-note@#get-int-typename {{candidate template ignored: invalid explicitly-specified argument: type argument 'int' is not compatible}}
template<template<class T> class, typename T> // expected-note {{template parameter is declared here}}
- void get(const T&); // expected-note {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ void get(const T&); // expected-note {{candidate template ignored: invalid explicitly-specified argument}}
void test_get(void *ptr) {
get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
>From f01257abe5ae432e27dd312737c3667b18252c2a Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 26 Feb 2025 11:19:56 -0500
Subject: [PATCH 31/31] test typo
---
clang/test/AST/ByteCode/cxx20.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index dfff819bf84d5..e7e3a05d64380 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -751,7 +751,7 @@ namespace FailingDestructor {
}
};
template<D d> // both-note{{template parameter is declared here}}
- void f() {} // both-note{{andidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ void f() {} // both-note{{candidate template ignored: invalid explicitly-specified argument}}
void g() {
f<D{0, false}>(); // both-error {{no matching function}}
More information about the cfe-commits
mailing list