[clang] ada6372 - Revert "[clang] Finish implementation of P0522 (#96023)"
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 8 23:41:57 PDT 2024
Author: Hans Wennborg
Date: 2024-10-09T08:41:42+02:00
New Revision: ada6372e52547ba0090f52a2e9e9d95d7eca28d3
URL: https://github.com/llvm/llvm-project/commit/ada6372e52547ba0090f52a2e9e9d95d7eca28d3
DIFF: https://github.com/llvm/llvm-project/commit/ada6372e52547ba0090f52a2e9e9d95d7eca28d3.diff
LOG: Revert "[clang] Finish implementation of P0522 (#96023)"
This caused Clang to reject valid code, see discussion on the PR
https://github.com/llvm/llvm-project/pull/96023#issuecomment-2393228464
and https://github.com/llvm/llvm-project/issues/111363
This reverts commit 6afe56732a172d3f2cbd0330b1fcb34bbfd002a9 and
follow-up commit 9abb97f9663a27fe5b8e346ed557b3435aa9ec2f.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Frontend/FrontendActions.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
clang/test/CXX/temp/temp.param/p12.cpp
clang/test/Modules/cxx-templates.cpp
clang/test/SemaCXX/make_integer_seq.cpp
clang/test/SemaTemplate/cwg2398.cpp
clang/test/SemaTemplate/temp_arg_nontype.cpp
clang/test/SemaTemplate/temp_arg_template.cpp
clang/test/SemaTemplate/temp_arg_template_p0522.cpp
clang/test/Templight/templight-empty-entries-fix.cpp
clang/test/Templight/templight-prior-template-arg.cpp
libcxx/test/libcxx/type_traits/is_specialization.verify.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8d02cc3eae9fd9..36e8126bcda6ad 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -174,10 +174,6 @@ C++23 Feature Support
C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
-C++17 Feature Support
-^^^^^^^^^^^^^^^^^^^^^
-- The implementation of the relaxed template template argument matching rules is
- more complete and reliable, and should provide more accurate diagnostics.
Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -335,10 +331,6 @@ Improvements to Clang's diagnostics
- Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391.
-- Clang now properly explains the reason a template template argument failed to
- match a template template parameter, in terms of the C++17 relaxed matching rules
- instead of the old ones.
-
- Don't emit duplicated dangling diagnostics. (#GH93386).
- Improved diagnostic when trying to befriend a concept. (#GH45182).
@@ -444,8 +436,6 @@ Bug Fixes to C++ Support
- Correctly check constraints of explicit instantiations of member functions. (#GH46029)
- When performing partial ordering of function templates, clang now checks that
the deduction was consistent. Fixes (#GH18291).
-- Fixes to several issues in partial ordering of template template parameters, which
- were documented in the test suite.
- Fixed an assertion failure about a constraint of a friend function template references to a value with greater
template depth than the friend function template. (#GH98258)
- Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 583475327c5227..057c3e6861a5fb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5262,13 +5262,6 @@ def note_template_arg_refers_here_func : Note<
def err_template_arg_template_params_mismatch : Error<
"template template argument has
diff erent template parameters than its "
"corresponding template template parameter">;
-def note_template_arg_template_params_mismatch : Note<
- "template template argument has
diff erent template parameters than its "
- "corresponding template template parameter">;
-def err_non_deduced_mismatch : Error<
- "could not match %
diff {$ against $|types}0,1">;
-def err_inconsistent_deduction : Error<
- "conflicting deduction %
diff {$ against $|types}0,1 for parameter">;
def err_template_arg_not_integral_or_enumeral : Error<
"non-type template argument of type %0 must have an integral or enumeration"
" type">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 043456438b6d03..86053bd7da1725 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12417,9 +12417,8 @@ class Sema final : public SemaBase {
sema::TemplateDeductionInfo &Info);
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(
- TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg,
- const DefaultArguments &DefaultArgs, SourceLocation ArgLoc,
- bool IsDeduced);
+ TemplateParameterList *PParam, TemplateDecl *AArg,
+ const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced);
/// Mark which template parameters are used in a given expression.
///
@@ -12728,9 +12727,6 @@ class Sema final : public SemaBase {
/// We are instantiating a type alias template declaration.
TypeAliasTemplateInstantiation,
-
- /// We are performing partial ordering for template template parameters.
- PartialOrderingTTP,
} Kind;
/// Was the enclosing context a non-instantiation SFINAE context?
@@ -12952,12 +12948,6 @@ class Sema final : public SemaBase {
TemplateDecl *Entity, BuildingDeductionGuidesTag,
SourceRange InstantiationRange = SourceRange());
- struct PartialOrderingTTP {};
- /// \brief Note that we are partial ordering template template parameters.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation ArgLoc,
- PartialOrderingTTP, TemplateDecl *PArg,
- SourceRange InstantiationRange = SourceRange());
-
/// Note that we have finished instantiating this template.
void Clear();
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index e4b462b9b0fd81..64f90c493c1055 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -457,8 +457,6 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
return "BuildingDeductionGuides";
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
return "TypeAliasTemplateInstantiation";
- case CodeSynthesisContext::PartialOrderingTTP:
- return "PartialOrderingTTP";
}
return "";
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b1a34edba9150b..dfd56debc75e99 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5498,7 +5498,8 @@ bool Sema::CheckTemplateArgumentList(
DefaultArgs && ParamIdx >= DefaultArgs.StartPos) {
// All written arguments should have been consumed by this point.
assert(ArgIdx == NumArgs && "bad default argument deduction");
- if (ParamIdx == DefaultArgs.StartPos) {
+ // FIXME: Don't ignore parameter packs.
+ if (ParamIdx == DefaultArgs.StartPos && !(*Param)->isParameterPack()) {
assert(Param + DefaultArgs.Args.size() <= ParamEnd);
// Default arguments from a DeducedTemplateName are already converted.
for (const TemplateArgument &DefArg : DefaultArgs.Args) {
@@ -5575,6 +5576,9 @@ bool Sema::CheckTemplateArgumentList(
return true;
}
+ // We're now done with this argument.
+ ++ArgIdx;
+
if ((*Param)->isTemplateParameterPack()) {
// The template parameter was a template parameter pack, so take the
// deduced argument and place it on the argument pack. Note that we
@@ -5585,19 +5589,8 @@ bool Sema::CheckTemplateArgumentList(
} else {
// Move to the next template parameter.
++Param;
- if (PartialOrderingTTP && PackExpansionIntoNonPack) {
- // Keep converting the pattern in the argument against
- // subsequent parameters. The argument is converted
- // in place and will be added back when we are done.
- SugaredConverted.pop_back();
- CanonicalConverted.pop_back();
- continue;
- }
}
- // We're now done with this argument.
- ++ArgIdx;
-
// If we just saw a pack expansion into a non-pack, then directly convert
// the remaining arguments, because we don't know what parameters they'll
// match up with.
@@ -5731,10 +5724,14 @@ bool Sema::CheckTemplateArgumentList(
// pack expansions; they might be empty. This can happen even if
// PartialTemplateArgs is false (the list of arguments is complete but
// still dependent).
- while (ArgIdx < NumArgs && NewArgs[ArgIdx].getArgument().isPackExpansion()) {
- const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument();
- SugaredConverted.push_back(Arg);
- CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
+ if (ArgIdx < NumArgs && CurrentInstantiationScope &&
+ CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ while (ArgIdx < NumArgs &&
+ NewArgs[ArgIdx].getArgument().isPackExpansion()) {
+ const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument();
+ SugaredConverted.push_back(Arg);
+ CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
+ }
}
// If we have any leftover arguments, then there were too many arguments.
@@ -7324,46 +7321,64 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
<< Template;
}
- if (!getLangOpts().RelaxedTemplateTemplateArgs)
- return !TemplateParameterListsAreEqual(
- Template->getTemplateParameters(), Params, /*Complain=*/true,
- TPL_TemplateTemplateArgumentMatch, Arg.getLocation());
-
// C++1z [temp.arg.template]p3: (DR 150)
// A template-argument matches a template template-parameter P when P
// is at least as specialized as the template-argument A.
- if (!isTemplateTemplateParameterAtLeastAsSpecializedAs(
- Params, Param, Template, DefaultArgs, Arg.getLocation(), IsDeduced))
- return true;
- // P2113
- // C++20[temp.func.order]p2
- // [...] If both deductions succeed, the partial ordering selects the
- // more constrained template (if one exists) as determined below.
- SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
- Params->getAssociatedConstraints(ParamsAC);
- // C++20[temp.arg.template]p3
- // [...] In this comparison, if P is unconstrained, the constraints on A
- // are not considered.
- if (ParamsAC.empty())
- return false;
+ if (getLangOpts().RelaxedTemplateTemplateArgs) {
+ // Quick check for the common case:
+ // If P contains a parameter pack, then A [...] matches P if each of A's
+ // template parameters matches the corresponding template parameter in
+ // the template-parameter-list of P.
+ if (TemplateParameterListsAreEqual(
+ Template->getTemplateParameters(), Params, false,
+ TPL_TemplateTemplateArgumentMatch, Arg.getLocation()) &&
+ // If the argument has no associated constraints, then the parameter is
+ // definitely at least as specialized as the argument.
+ // Otherwise - we need a more thorough check.
+ !Template->hasAssociatedConstraints())
+ return false;
- Template->getAssociatedConstraints(TemplateAC);
+ if (isTemplateTemplateParameterAtLeastAsSpecializedAs(
+ Params, Template, DefaultArgs, Arg.getLocation(), IsDeduced)) {
+ // P2113
+ // C++20[temp.func.order]p2
+ // [...] If both deductions succeed, the partial ordering selects the
+ // more constrained template (if one exists) as determined below.
+ SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
+ Params->getAssociatedConstraints(ParamsAC);
+ // C++2a[temp.arg.template]p3
+ // [...] In this comparison, if P is unconstrained, the constraints on A
+ // are not considered.
+ if (ParamsAC.empty())
+ return false;
- bool IsParamAtLeastAsConstrained;
- if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
- IsParamAtLeastAsConstrained))
- return true;
- if (!IsParamAtLeastAsConstrained) {
- Diag(Arg.getLocation(),
- diag::err_template_template_parameter_not_at_least_as_constrained)
- << Template << Param << Arg.getSourceRange();
- Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
- Diag(Template->getLocation(), diag::note_entity_declared_at) << Template;
- MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
- TemplateAC);
- return true;
+ Template->getAssociatedConstraints(TemplateAC);
+
+ bool IsParamAtLeastAsConstrained;
+ if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
+ IsParamAtLeastAsConstrained))
+ return true;
+ if (!IsParamAtLeastAsConstrained) {
+ Diag(Arg.getLocation(),
+ diag::err_template_template_parameter_not_at_least_as_constrained)
+ << Template << Param << Arg.getSourceRange();
+ Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
+ Diag(Template->getLocation(), diag::note_entity_declared_at)
+ << Template;
+ MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
+ TemplateAC);
+ return true;
+ }
+ return false;
+ }
+ // FIXME: Produce better diagnostics for deduction failures.
}
- return false;
+
+ return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
+ Params,
+ true,
+ TPL_TemplateTemplateArgumentMatch,
+ Arg.getLocation());
}
static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl,
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f9a8d2d9ff0b1d..dfae0d6cda0d9b 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -145,9 +145,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
PartialOrderingKind POK, bool DeducedFromArrayBound,
bool *HasDeducedAnyParam);
-/// What directions packs are allowed to match non-packs.
-enum class PackFold { ParameterToArgument, ArgumentToParameter, Both };
-
+enum class PackFold { ParameterToArgument, ArgumentToParameter };
static TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
ArrayRef<TemplateArgument> Ps,
@@ -1713,21 +1711,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
DeducedTemplateArgument Result =
checkDeducedTemplateArguments(S.Context, Deduced[Index], NewDeduced);
if (Result.isNull()) {
- // We can also get inconsistencies when matching NTTP type.
- switch (NamedDecl *Param = TemplateParams->getParam(Index);
- Param->getKind()) {
- case Decl::TemplateTypeParm:
- Info.Param = cast<TemplateTypeParmDecl>(Param);
- break;
- case Decl::NonTypeTemplateParm:
- Info.Param = cast<NonTypeTemplateParmDecl>(Param);
- break;
- case Decl::TemplateTemplateParm:
- Info.Param = cast<TemplateTemplateParmDecl>(Param);
- break;
- default:
- llvm_unreachable("unexpected kind");
- }
+ Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = Deduced[Index];
Info.SecondArg = NewDeduced;
return TemplateDeductionResult::Inconsistent;
@@ -2565,31 +2549,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
if (const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, P.getAsExpr())) {
switch (A.getKind()) {
- case TemplateArgument::Expression: {
- const Expr *E = A.getAsExpr();
- // When checking NTTP, if either the parameter or the argument is
- // dependent, as there would be otherwise nothing to deduce, we force
- // the argument to the parameter type using this dependent implicit
- // cast, in order to maintain invariants. Now we can deduce the
- // resulting type from the original type, and deduce the original type
- // against the parameter we are checking.
- if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
- ICE && ICE->getCastKind() == clang::CK_Dependent) {
- E = ICE->getSubExpr();
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, ICE->getType(), E->getType(), Info,
- Deduced, TDF_SkipNonDependent,
- PartialOrdering ? PartialOrderingKind::NonCall
- : PartialOrderingKind::None,
- /*DeducedFromArrayBound=*/false, HasDeducedAnyParam);
- Result != TemplateDeductionResult::Success)
- return Result;
- }
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, DeducedTemplateArgument(A), E->getType(),
- Info, PartialOrdering, Deduced, HasDeducedAnyParam);
- }
case TemplateArgument::Integral:
+ case TemplateArgument::Expression:
case TemplateArgument::StructuralValue:
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, DeducedTemplateArgument(A),
@@ -2678,75 +2639,50 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch, bool PartialOrdering,
PackFold PackFold, bool *HasDeducedAnyParam) {
- bool FoldPackParameter = PackFold == PackFold::ParameterToArgument ||
- PackFold == PackFold::Both,
- FoldPackArgument = PackFold == PackFold::ArgumentToParameter ||
- PackFold == PackFold::Both;
-
+ if (PackFold == PackFold::ArgumentToParameter)
+ std::swap(Ps, As);
// C++0x [temp.deduct.type]p9:
// If the template argument list of P contains a pack expansion that is not
// the last template argument, the entire template argument list is a
// non-deduced context.
- if (FoldPackParameter && hasPackExpansionBeforeEnd(Ps))
- return TemplateDeductionResult::Success;
-
- if (FoldPackArgument && hasPackExpansionBeforeEnd(As))
+ if (hasPackExpansionBeforeEnd(Ps))
return TemplateDeductionResult::Success;
// C++0x [temp.deduct.type]p9:
// If P has a form that contains <T> or <i>, then each argument Pi of the
// respective template argument list P is compared with the corresponding
// argument Ai of the corresponding template argument list of A.
- for (unsigned ArgIdx = 0, ParamIdx = 0; /**/; /**/) {
- if (!hasTemplateArgumentForDeduction(Ps, ParamIdx))
- return !FoldPackParameter && hasTemplateArgumentForDeduction(As, ArgIdx)
- ? TemplateDeductionResult::MiscellaneousDeductionFailure
- : TemplateDeductionResult::Success;
-
- if (!Ps[ParamIdx].isPackExpansion()) {
+ unsigned ArgIdx = 0, ParamIdx = 0;
+ for (; hasTemplateArgumentForDeduction(Ps, ParamIdx); ++ParamIdx) {
+ const TemplateArgument &P = Ps[ParamIdx];
+ if (!P.isPackExpansion()) {
// The simple case: deduce template arguments by matching Pi and Ai.
// Check whether we have enough arguments.
if (!hasTemplateArgumentForDeduction(As, ArgIdx))
- return !FoldPackArgument && NumberOfArgumentsMustMatch
+ return NumberOfArgumentsMustMatch
? TemplateDeductionResult::MiscellaneousDeductionFailure
: TemplateDeductionResult::Success;
- if (As[ArgIdx].isPackExpansion()) {
- // C++1z [temp.deduct.type]p9:
- // During partial ordering, if Ai was originally a pack expansion
- // [and] Pi is not a pack expansion, template argument deduction
- // fails.
- if (!FoldPackArgument)
- return TemplateDeductionResult::MiscellaneousDeductionFailure;
-
- TemplateArgument Pattern = As[ArgIdx].getPackExpansionPattern();
- for (;;) {
- // Deduce template parameters from the pattern.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, Ps[ParamIdx], Pattern, Info,
- PartialOrdering, Deduced, HasDeducedAnyParam);
- Result != TemplateDeductionResult::Success)
- return Result;
+ // C++1z [temp.deduct.type]p9:
+ // During partial ordering, if Ai was originally a pack expansion [and]
+ // Pi is not a pack expansion, template argument deduction fails.
+ if (As[ArgIdx].isPackExpansion())
+ return TemplateDeductionResult::MiscellaneousDeductionFailure;
- ++ParamIdx;
- if (!hasTemplateArgumentForDeduction(Ps, ParamIdx))
- return TemplateDeductionResult::Success;
- if (Ps[ParamIdx].isPackExpansion())
- break;
- }
- } else {
- // Perform deduction for this Pi/Ai pair.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, Ps[ParamIdx], As[ArgIdx], Info,
- PartialOrdering, Deduced, HasDeducedAnyParam);
- Result != TemplateDeductionResult::Success)
- return Result;
+ // Perform deduction for this Pi/Ai pair.
+ TemplateArgument Pi = P, Ai = As[ArgIdx];
+ if (PackFold == PackFold::ArgumentToParameter)
+ std::swap(Pi, Ai);
+ if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pi, Ai, Info,
+ PartialOrdering, Deduced,
+ HasDeducedAnyParam);
+ Result != TemplateDeductionResult::Success)
+ return Result;
- ++ArgIdx;
- ++ParamIdx;
- continue;
- }
+ // Move to the next argument.
+ ++ArgIdx;
+ continue;
}
// The parameter is a pack expansion.
@@ -2756,7 +2692,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
// each remaining argument in the template argument list of A. Each
// comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by Pi.
- TemplateArgument Pattern = Ps[ParamIdx].getPackExpansionPattern();
+ TemplateArgument Pattern = P.getPackExpansionPattern();
// Prepare to deduce the packs within the pattern.
PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
@@ -2767,12 +2703,13 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
for (; hasTemplateArgumentForDeduction(As, ArgIdx) &&
PackScope.hasNextElement();
++ArgIdx) {
- if (!FoldPackParameter && !As[ArgIdx].isPackExpansion())
- return TemplateDeductionResult::MiscellaneousDeductionFailure;
+ TemplateArgument Pi = Pattern, Ai = As[ArgIdx];
+ if (PackFold == PackFold::ArgumentToParameter)
+ std::swap(Pi, Ai);
// Deduce template arguments from the pattern.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, Pattern, As[ArgIdx], Info, PartialOrdering,
- Deduced, HasDeducedAnyParam);
+ if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pi, Ai, Info,
+ PartialOrdering, Deduced,
+ HasDeducedAnyParam);
Result != TemplateDeductionResult::Success)
return Result;
@@ -2781,8 +2718,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- return PackScope.finish();
+ if (auto Result = PackScope.finish();
+ Result != TemplateDeductionResult::Success)
+ return Result;
}
+
+ return TemplateDeductionResult::Success;
}
TemplateDeductionResult Sema::DeduceTemplateArguments(
@@ -3334,6 +3275,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::Unevaluated);
+ Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template));
@@ -3350,42 +3292,21 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
return Result;
// Check that we produced the correct argument list.
- for (ArrayRef<TemplateArgument> Ps = TemplateArgs, As = CanonicalBuilder;
- !Ps.empty() && !As.empty();
- /**/) {
- TemplateArgument P = Ps.front(), A = As.front();
- if (P.getKind() == TemplateArgument::Pack) {
- assert(Ps.size() == 1 && "Pack not last element?");
- Ps = P.getPackAsArray();
- continue;
- }
- if (A.getKind() == TemplateArgument::Pack) {
- assert(As.size() == 1 && "Pack not last element?");
- As = A.getPackAsArray();
- continue;
+ TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+ for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
+ TemplateArgument InstArg = CanonicalBuilder[I];
+ if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg, PartialOrdering,
+ /*PackExpansionMatchesPack=*/true)) {
+ Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
+ Info.FirstArg = TemplateArgs[I];
+ Info.SecondArg = InstArg;
+ return TemplateDeductionResult::NonDeducedMismatch;
}
-
- if (P.isPackExpansion())
- P = P.getPackExpansionPattern();
- else
- Ps = Ps.drop_front();
- if (A.isPackExpansion())
- A = A.getPackExpansionPattern();
- else
- As = As.drop_front();
-
- if (isSameTemplateArg(S.Context, P, A, PartialOrdering))
- continue;
- unsigned I = As.end() == CanonicalBuilder.end()
- ? As.begin() - CanonicalBuilder.begin()
- : CanonicalBuilder.size() - 1;
- Info.Param =
- makeTemplateParameter(Template->getTemplateParameters()->getParam(I));
- Info.FirstArg = P;
- Info.SecondArg = A;
- return TemplateDeductionResult::NonDeducedMismatch;
}
+ if (Trap.hasErrorOccurred())
+ return TemplateDeductionResult::SubstitutionFailure;
+
if (!PartialOrdering) {
if (auto Result = CheckDeducedArgumentConstraints(
S, Template, SugaredBuilder, CanonicalBuilder, Info);
@@ -3406,6 +3327,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::Unevaluated);
+ Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(TD));
@@ -3414,13 +3336,20 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
if (auto Result = ConvertDeducedTemplateArguments(
- S, TD, /*IsDeduced=*/false, Deduced, Info, SugaredBuilder,
+ S, TD, /*IsPartialOrdering=*/false, Deduced, Info, SugaredBuilder,
CanonicalBuilder);
Result != TemplateDeductionResult::Success)
return Result;
- return ::CheckDeducedArgumentConstraints(S, TD, SugaredBuilder,
- CanonicalBuilder, Info);
+ if (Trap.hasErrorOccurred())
+ return TemplateDeductionResult::SubstitutionFailure;
+
+ if (auto Result = CheckDeducedArgumentConstraints(S, TD, SugaredBuilder,
+ CanonicalBuilder, Info);
+ Result != TemplateDeductionResult::Success)
+ return Result;
+
+ return TemplateDeductionResult::Success;
}
/// Perform template argument deduction to determine whether the given template
@@ -3467,20 +3396,16 @@ DeduceTemplateArguments(Sema &S, T *Partial,
if (Inst.isInvalid())
return TemplateDeductionResult::InstantiationDepth;
+ if (Trap.hasErrorOccurred())
+ return TemplateDeductionResult::SubstitutionFailure;
+
TemplateDeductionResult Result;
S.runWithSufficientStackSpace(Info.getLocation(), [&] {
Result = ::FinishTemplateArgumentDeduction(S, Partial,
/*IsPartialOrdering=*/false,
TemplateArgs, Deduced, Info);
});
-
- if (Result != TemplateDeductionResult::Success)
- return Result;
-
- if (Trap.hasErrorOccurred())
- return TemplateDeductionResult::SubstitutionFailure;
-
- return TemplateDeductionResult::Success;
+ return Result;
}
TemplateDeductionResult
@@ -3536,18 +3461,14 @@ Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
if (Inst.isInvalid())
return TemplateDeductionResult::InstantiationDepth;
+ if (Trap.hasErrorOccurred())
+ return TemplateDeductionResult::SubstitutionFailure;
+
TemplateDeductionResult Result;
runWithSufficientStackSpace(Info.getLocation(), [&] {
Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
});
-
- if (Result != TemplateDeductionResult::Success)
- return Result;
-
- if (Trap.hasErrorOccurred())
- return TemplateDeductionResult::SubstitutionFailure;
-
- return TemplateDeductionResult::Success;
+ return Result;
}
/// Determine whether the given type T is a simple-template-id type.
@@ -6173,23 +6094,14 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,
return false;
const auto *TST1 = cast<TemplateSpecializationType>(T1);
-
- Sema::SFINAETrap Trap(S);
-
- TemplateDeductionResult Result;
+ bool AtLeastAsSpecialized;
S.runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = ::FinishTemplateArgumentDeduction(
- S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(), Deduced,
- Info);
+ AtLeastAsSpecialized =
+ FinishTemplateArgumentDeduction(
+ S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(),
+ Deduced, Info) == TemplateDeductionResult::Success;
});
-
- if (Result != TemplateDeductionResult::Success)
- return false;
-
- if (Trap.hasErrorOccurred())
- return false;
-
- return true;
+ return AtLeastAsSpecialized;
}
namespace {
@@ -6427,9 +6339,8 @@ bool Sema::isMoreSpecializedThanPrimary(
}
bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
- TemplateParameterList *P, TemplateDecl *PArg, TemplateDecl *AArg,
- const DefaultArguments &DefaultArgs, SourceLocation ArgLoc,
- bool IsDeduced) {
+ TemplateParameterList *P, TemplateDecl *AArg,
+ const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced) {
// C++1z [temp.arg.template]p4: (DR 150)
// A template template-parameter P is at least as specialized as a
// template template-argument A if, given the following rewrite to two
@@ -6441,12 +6352,6 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
//
TemplateParameterList *A = AArg->getTemplateParameters();
- Sema::InstantiatingTemplate Inst(
- *this, ArgLoc, Sema::InstantiatingTemplate::PartialOrderingTTP(), PArg,
- SourceRange(P->getTemplateLoc(), P->getRAngleLoc()));
- if (Inst.isInvalid())
- return false;
-
// Given an invented class template X with the template parameter list of
// A (including default arguments):
// - Each function template has a single function parameter whose type is
@@ -6461,6 +6366,8 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
// templates.
SmallVector<TemplateArgument, 4> PArgs;
{
+ SFINAETrap Trap(*this);
+
Context.getInjectedTemplateArgs(P, PArgs);
TemplateArgumentListInfo PArgList(P->getLAngleLoc(),
P->getRAngleLoc());
@@ -6480,17 +6387,18 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
// C++1z [temp.arg.template]p3:
// If the rewrite produces an invalid type, then P is not at least as
// specialized as A.
- SmallVector<TemplateArgument, 4> CanonicalPArgs;
- if (CheckTemplateArgumentList(AArg, ArgLoc, PArgList, DefaultArgs, false,
- PArgs, CanonicalPArgs,
+ SmallVector<TemplateArgument, 4> SugaredPArgs;
+ if (CheckTemplateArgumentList(AArg, Loc, PArgList, DefaultArgs, false,
+ SugaredPArgs, PArgs,
/*UpdateArgsWithConversions=*/true,
/*ConstraintsNotSatisfied=*/nullptr,
- /*PartialOrderingTTP=*/true))
+ /*PartialOrderTTP=*/true) ||
+ Trap.hasErrorOccurred())
return false;
}
// Determine whether P1 is at least as specialized as P2.
- TemplateDeductionInfo Info(ArgLoc, A->getDepth());
+ TemplateDeductionInfo Info(Loc, A->getDepth());
SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(A->size());
@@ -6505,89 +6413,29 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
// be inverted between Ps and As. On non-deduced context, matching needs to
// happen both ways, according to [temp.arg.template]p3, but this is
// currently implemented as a special case elsewhere.
- switch (::DeduceTemplateArguments(
- *this, A, AArgs, PArgs, Info, Deduced,
- /*NumberOfArgumentsMustMatch=*/false, /*PartialOrdering=*/true,
- IsDeduced ? PackFold::ArgumentToParameter : PackFold::Both,
- /*HasDeducedAnyParam=*/nullptr)) {
- case clang::TemplateDeductionResult::Success:
- break;
-
- case TemplateDeductionResult::MiscellaneousDeductionFailure:
- Diag(AArg->getLocation(), diag::err_template_param_list_
diff erent_arity)
- << (A->size() > P->size()) << /*isTemplateTemplateParameter=*/true
- << SourceRange(A->getTemplateLoc(), P->getRAngleLoc());
+ if (::DeduceTemplateArguments(*this, A, AArgs, PArgs, Info, Deduced,
+ /*NumberOfArgumentsMustMatch=*/false,
+ /*PartialOrdering=*/true,
+ IsDeduced ? PackFold::ArgumentToParameter
+ : PackFold::ParameterToArgument,
+ /*HasDeducedAnyParam=*/nullptr) !=
+ TemplateDeductionResult::Success)
return false;
- case TemplateDeductionResult::NonDeducedMismatch:
- Diag(AArg->getLocation(), diag::err_non_deduced_mismatch)
- << Info.FirstArg << Info.SecondArg;
- return false;
- case TemplateDeductionResult::Inconsistent:
- Diag(getAsNamedDecl(Info.Param)->getLocation(),
- diag::err_inconsistent_deduction)
- << Info.FirstArg << Info.SecondArg;
- return false;
- case TemplateDeductionResult::AlreadyDiagnosed:
- return false;
-
- // None of these should happen for a plain deduction.
- case TemplateDeductionResult::Invalid:
- case TemplateDeductionResult::InstantiationDepth:
- case TemplateDeductionResult::Incomplete:
- case TemplateDeductionResult::IncompletePack:
- case TemplateDeductionResult::Underqualified:
- case TemplateDeductionResult::SubstitutionFailure:
- case TemplateDeductionResult::DeducedMismatch:
- case TemplateDeductionResult::DeducedMismatchNested:
- case TemplateDeductionResult::TooManyArguments:
- case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
- case TemplateDeductionResult::NonDependentConversionFailure:
- case TemplateDeductionResult::ConstraintsNotSatisfied:
- case TemplateDeductionResult::CUDATargetMismatch:
- llvm_unreachable("Unexpected Result");
- }
SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
+ Sema::InstantiatingTemplate Inst(*this, Info.getLocation(), AArg, DeducedArgs,
+ Info);
+ if (Inst.isInvalid())
+ return false;
- TemplateDeductionResult TDK;
+ bool AtLeastAsSpecialized;
runWithSufficientStackSpace(Info.getLocation(), [&] {
- TDK = ::FinishTemplateArgumentDeduction(
- *this, AArg, /*IsPartialOrdering=*/true, PArgs, Deduced, Info);
+ AtLeastAsSpecialized =
+ ::FinishTemplateArgumentDeduction(
+ *this, AArg, /*IsPartialOrdering=*/true, PArgs, Deduced, Info) ==
+ TemplateDeductionResult::Success;
});
- switch (TDK) {
- case TemplateDeductionResult::Success:
- return true;
-
- // It doesn't seem possible to get a non-deduced mismatch when partial
- // ordering TTPs.
- case TemplateDeductionResult::NonDeducedMismatch:
- llvm_unreachable("Unexpected NonDeducedMismatch");
-
- // Substitution failures should have already been diagnosed.
- case TemplateDeductionResult::AlreadyDiagnosed:
- case TemplateDeductionResult::SubstitutionFailure:
- case TemplateDeductionResult::InstantiationDepth:
- return false;
-
- // None of these should happen when just converting deduced arguments.
- case TemplateDeductionResult::Invalid:
- case TemplateDeductionResult::Incomplete:
- case TemplateDeductionResult::IncompletePack:
- case TemplateDeductionResult::Inconsistent:
- case TemplateDeductionResult::Underqualified:
- case TemplateDeductionResult::DeducedMismatch:
- case TemplateDeductionResult::DeducedMismatchNested:
- case TemplateDeductionResult::TooManyArguments:
- case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
- case TemplateDeductionResult::NonDependentConversionFailure:
- case TemplateDeductionResult::ConstraintsNotSatisfied:
- case TemplateDeductionResult::MiscellaneousDeductionFailure:
- case TemplateDeductionResult::CUDATargetMismatch:
- llvm_unreachable("Unexpected Result");
- }
- llvm_unreachable("Unexpected TDK");
+ return AtLeastAsSpecialized;
}
namespace {
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9c5b3e7c9066c7..261ef4edf17593 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -573,7 +573,6 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
case LambdaExpressionSubstitution:
case BuildingDeductionGuides:
case TypeAliasTemplateInstantiation:
- case PartialOrderingTTP:
return false;
// This function should never be called when Kind's value is Memoization.
@@ -806,11 +805,6 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
SemaRef, CodeSynthesisContext::BuildingDeductionGuides,
PointOfInstantiation, InstantiationRange, Entity) {}
-Sema::InstantiatingTemplate::InstantiatingTemplate(
- Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP,
- TemplateDecl *PArg, SourceRange InstantiationRange)
- : InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP,
- ArgLoc, InstantiationRange, PArg) {}
void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
@@ -1250,14 +1244,6 @@ void Sema::PrintInstantiationStack() {
<< cast<TypeAliasTemplateDecl>(Active->Entity)
<< Active->InstantiationRange;
break;
- case CodeSynthesisContext::PartialOrderingTTP:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_arg_template_params_mismatch);
- if (SourceLocation ParamLoc = Active->Entity->getLocation();
- ParamLoc.isValid())
- Diags.Report(ParamLoc, diag::note_template_prev_declaration)
- << /*isTemplateTemplateParam=*/true << Active->InstantiationRange;
- break;
}
}
}
@@ -1300,7 +1286,6 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
case CodeSynthesisContext::DefaultTemplateArgumentChecking:
case CodeSynthesisContext::RewritingOperatorAsSpaceship:
- case CodeSynthesisContext::PartialOrderingTTP:
// A default template argument instantiation and substitution into
// template parameters with arguments for prior parameters may or may
// not be a SFINAE context; look further up the stack.
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
index ce27e6aa83c3b9..19793fe8263726 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
@@ -2,13 +2,13 @@
template <class T> struct eval; // expected-note 3{{template is declared here}}
-template <template <class, class...> class TT, class T1, class... Rest>
+template <template <class, class...> class TT, class T1, class... Rest>
struct eval<TT<T1, Rest...>> { };
-template <class T1> struct A;
-template <class T1, class T2> struct B;
-template <int N> struct C;
-template <class T1, int N> struct D;
+template <class T1> struct A;
+template <class T1, class T2> struct B;
+template <int N> struct C;
+template <class T1, int N> struct D;
template <class T1, class T2, int N = 17> struct E;
eval<A<int>> eA;
@@ -17,32 +17,27 @@ eval<C<17>> eC; // expected-error{{implicit instantiation of undefined template
eval<D<int, 17>> eD; // expected-error{{implicit instantiation of undefined template 'eval<D<int, 17>>'}}
eval<E<int, float>> eE; // expected-error{{implicit instantiation of undefined template 'eval<E<int, float>>}}
-template<
- template <int ...N> // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('long' vs 'int')}}
- class TT // expected-note {{previous template template parameter is here}}
-> struct X0 { };
-
+template<template <int ...N> class TT> struct X0 { }; // expected-note{{previous non-type template parameter with type 'int' is here}}
template<int I, int J, int ...Rest> struct X0a;
template<int ...Rest> struct X0b;
-template<int I, long J> struct X0c; // expected-note{{template parameter is declared here}}
+template<int I, long J> struct X0c; // expected-note{{template non-type parameter has a
diff erent type 'long' in template argument}}
X0<X0a> inst_x0a;
X0<X0b> inst_x0b;
-X0<X0c> inst_x0c; // expected-note{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
+X0<X0c> inst_x0c; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
-template<typename T,
- template <T ...N> // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('long' vs 'short')}}
- class TT // expected-note {{previous template template parameter is here}}
-> struct X1 { };
+template<typename T,
+ template <T ...N> class TT> // expected-note{{previous non-type template parameter with type 'short' is here}}
+struct X1 { };
template<int I, int J, int ...Rest> struct X1a;
template<long I, long ...Rest> struct X1b;
template<short I, short J> struct X1c;
-template<short I, long J> struct X1d; // expected-note{{template parameter is declared here}}
+template<short I, long J> struct X1d; // expected-note{{template non-type parameter has a
diff erent type 'long' in template argument}}
X1<int, X1a> inst_x1a;
X1<long, X1b> inst_x1b;
X1<short, X1c> inst_x1c;
-X1<short, X1d> inst_x1d; // expected-note{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
+X1<short, X1d> inst_x1d; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template paramete}}
template <int> class X2; // expected-note{{template is declared here}} \
// expected-note{{template is declared here}}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index fbda7cbe696bb0..51df1e0b14541b 100644
--- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -29,14 +29,10 @@ namespace PackExpansionNotAtEnd {
>::value? 1 : -1];
template<typename ... Types> struct UselessPartialSpec;
- // expected-note at -1 {{template is declared here}}
- // FIXME: We should simply disallow a pack expansion which is not at
- // the end of the partial spec template argument list.
template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
struct UselessPartialSpec<Types..., Tail>; // expected-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
- // expected-error at -1 {{is not more specialized than the primary template}}
}
// When a pack expansion occurs within a template argument list, the entire
diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp
index 8317e7f24152cc..7be38790905fa3 100644
--- a/clang/test/CXX/temp/temp.param/p12.cpp
+++ b/clang/test/CXX/temp/temp.param/p12.cpp
@@ -1,40 +1,39 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-template<typename> struct Y1; // expected-note{{template is declared here}}
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct Y1; // expected-note{{too few template parameters in template template argument}}
template<typename, int> struct Y2;
// C++ [temp.param]p12:
-template<class T1,
+template<class T1,
class T2 = int> // expected-note{{previous default template argument defined here}}
class B3;
template<class T1, typename T2> class B3;
-template<class T1,
+template<class T1,
typename T2 = float> // expected-error{{template parameter redefines default argument}}
class B3;
-template<template<class, int> class,
+template<template<class, int> class,
template<class> class = Y1> // expected-note{{previous default template argument defined here}}
class B3t;
template<template<class, int> class, template<class> class> class B3t;
-template<template<class, int> class,
+template<template<class, int> class,
template<class> class = Y1> // expected-error{{template parameter redefines default argument}}
class B3t;
-template<int N,
+template<int N,
int M = 5> // expected-note{{previous default template argument defined here}}
class B3n;
template<int N, int M> class B3n;
-template<int N,
+template<int N,
int M = 7> // expected-error{{template parameter redefines default argument}}
class B3n;
// Check validity of default arguments
-template<template<class, int> class =// expected-note {{previous template template parameter is here}}
- Y1> // expected-error{{too many template arguments for class template 'Y1'}}
- // expected-note at -1 {{template template argument has
diff erent template parameters than its corresponding template template parameter}}
+template<template<class, int> class // expected-note{{previous template template parameter is here}}
+ = Y1> // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
class C1 {};
C1<> c1; // expected-note{{while checking a default template argument}}
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index da5fc6ba4cea9a..44b02ad3ec748c 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -40,14 +40,23 @@ void g() {
template_param_kinds_1<0>(); // ok, from cxx-templates-a.h
template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
- template_param_kinds_2<Tmpl_T_C>(); // 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 {{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-a.h:11 {{candidate}}
// expected-note at Inputs/cxx-templates-b.h:11 {{candidate}}
- template_param_kinds_3<Tmpl_T_T_A>();
- template_param_kinds_3<Tmpl_T_T_B>();
+ // FIXME: This should be valid, but we incorrectly match the template template
+ // argument against both template template parameters.
+ template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}}
+ // expected-note at Inputs/cxx-templates-a.h:12 {{candidate}}
+ // expected-note at Inputs/cxx-templates-b.h:12 {{candidate}}
+ template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}}
+ // expected-note at Inputs/cxx-templates-a.h:12 {{candidate}}
+ // expected-note at Inputs/cxx-templates-b.h:12 {{candidate}}
// Trigger the instantiation of a template in 'a' that uses a type defined in
// 'common'. That type is not visible here.
diff --git a/clang/test/SemaCXX/make_integer_seq.cpp b/clang/test/SemaCXX/make_integer_seq.cpp
index 71b7b8260d4abc..8f72ce15eef476 100644
--- a/clang/test/SemaCXX/make_integer_seq.cpp
+++ b/clang/test/SemaCXX/make_integer_seq.cpp
@@ -48,5 +48,6 @@ using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}}
template <typename T, T N> void f() {}
__make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}}
-__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{
diff erent template parameters}}
-// expected-error at make_integer_seq.cpp:* {{template argument for template template parameter must be a class template or type alias template}}
+__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-error{{
diff erent template parameters}}
+// expected-note at make_integer_seq.cpp:* {{template parameter has a
diff erent kind}}
+// expected-note at make_integer_seq.cpp:* {{previous template template parameter is here}}
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 1b55af782fcb7c..6dc7af6ea17899 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -106,10 +106,12 @@ namespace type_pack3 {
template<class T3> struct B;
template<template<class T4 > class TT1, class T5 > struct B<TT1<T5 >>;
-
- template<template<class T6, class ...T7s> class TT2, class T8, class ...T9s> struct B<TT2<T8, T9s...>> {};
+ // new-note at -1 {{template is declared here}}
+ template<template<class T6, class ...T7s> class TT2, class T8, class ...T9s> struct B<TT2<T8, T9s...>>;
+ // old-note at -1 {{template is declared here}}
template struct B<A<int>>;
+ // expected-error at -1 {{explicit instantiation of undefined template}}
} // namespace type_pack3
namespace gcc_issue {
@@ -362,73 +364,6 @@ namespace classes {
} // namespace defaulted
} // namespace classes
-namespace packs {
- namespace t1 {
- // FIXME: This should be rejected
- template<template<int, int...> class> struct A {};
- // old-note at -1 {{previous non-type template parameter with type 'int' is here}}
-
- template<char> struct B;
- // old-note at -1 {{template non-type parameter has a
diff erent type 'char' in template argument}}
-
- template struct A<B>;
- // old-error at -1 {{has
diff erent template parameters}}
- } // namespace t1
- namespace t2 {
- template<template<char, int...> class> struct A {};
- // old-note at -1 {{previous non-type template parameter with type 'char' is here}}
-
- template<int> struct B;
- // old-note at -1 {{template non-type parameter has a
diff erent type 'int' in template argument}}
-
- template struct A<B>;
- // old-error at -1 {{has
diff erent template parameters}}
- } // namespace t2
- namespace t3 {
- // FIXME: This should be rejected
- template<template<int...> class> struct A {};
- // old-note at -1 {{previous non-type template parameter with type 'int' is here}}
-
- template<char> struct B;
- // old-note at -1 {{template non-type parameter has a
diff erent type 'char' in template argument}}
-
- template struct A<B>;
- // old-error at -1 {{has
diff erent template parameters}}
- } // namespace t3
- namespace t4 {
- template<template<char...> class> struct A {};
- // old-note at -1 {{previous non-type template parameter with type 'char' is here}}
-
- template<int> struct B;
- // old-note at -1 {{template non-type parameter has a
diff erent type 'int' in template argument}}
-
- template struct A<B>;
- // old-error at -1 {{has
diff erent template parameters}}
- } // namespace t4
-} // namespace packs
-
-namespace partial {
- namespace t1 {
- template<template<class... T1s> class TT1> struct A {};
-
- template<template<class T2> class TT2> struct A<TT2>;
- // new-note at -1 {{template is declared here}}
-
- template<class... T3s> struct B;
- template struct A<B>;
- // new-error at -1 {{explicit instantiation of undefined template}}
- } // namespace t1
- namespace t2 {
- template<template<class... T1s> class TT1> struct A;
-
- template<template<class T2> class TT2> struct A<TT2> {};
-
- template<class T3> struct B;
- template struct A<B>;
- } // namespace t1
-
-} // namespace partial
-
namespace regression1 {
template <typename T, typename Y> struct map {};
template <typename T> class foo {};
@@ -445,93 +380,6 @@ namespace regression1 {
}
} // namespace regression1
-namespace constraints {
- template <class T> concept C1 = true;
- // new-note at -1 {{similar constraint expression here}}
- // new-note at -2 2{{similar constraint expressions not considered equivalent}}
-
- template <class T> concept C2 = C1<T> && true;
- // new-note at -1 2{{similar constraint expression here}}
-
- template <class T> concept D1 = true;
- // new-note at -1 {{similar constraint expressions not considered equivalent}}
-
- namespace t1 {
- template<template<C1, class... T1s> class TT1> // new-note {{TT1' declared here}}
- struct A {};
- template<D1, class T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t1
- namespace t2 {
- template<template<C2, class... T1s> class TT1> struct A {};
- template<C1, class T2> struct B {};
- template struct A<B>;
- } // namespace t2
- namespace t3 {
- template<template<C1, class... T1s> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
- template<C2, class T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t2
- namespace t4 {
- // FIXME: This should be accepted.
- template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
- template<C1 T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t4
- namespace t5 {
- // FIXME: This should be accepted
- template<template<C2... T1s> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
- template<C1 T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t5
- namespace t6 {
- template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
- template<C2 T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t6
- namespace t7 {
- template<template<class... T1s> class TT1>
- struct A {};
- template<C1 T2> struct B {};
- template struct A<B>;
- } // namespace t7
- namespace t8 {
- template<template<C1... T1s> class TT1>
- struct A {};
- template<class T2> struct B {};
- template struct A<B>;
- } // namespace t8
- namespace t9 {
- template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
- template<D1 T2> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t9
- namespace t10 {
- template<template<class...> requires C1<int> class TT1> // new-note {{'TT1' declared here}}
- struct A {};
-
- template<class> requires C2<int> struct B {}; // new-note {{'B' declared here}}
- template struct A<B>;
- // new-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
- } // namespace t10
- namespace t11 {
- template<template<class...> requires C2<int> class TT1> struct A {};
- template<class> requires C1<int> struct B {};
- template struct A<B>;
- } // namespace t11
-} // namespace constraints
-
namespace regression2 {
template <class> struct D {};
@@ -541,9 +389,3 @@ namespace regression2 {
template <typename, int> struct Matrix;
template struct D<Matrix<double, 3>>;
} // namespace regression2
-
-namespace regression3 {
- template <template <auto...> class TT> struct A {};
- template <auto, int> struct B;
- template struct A<B>;
-} // namespace regression3
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 8b270b22a12b46..f360aa14950edd 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -387,11 +387,12 @@ namespace PR17696 {
namespace partial_order_
diff erent_types {
template<int, int, typename T, typename, T> struct A;
- // expected-note at -1 {{template is declared here}}
- template<int N, typename T, typename U, T V> struct A<0, N, T, U, V> {};
- template<int N, typename T, typename U, U V> struct A<0, N, T, U, V>;
- // expected-error at -1 {{class template partial specialization is not more specialized than the primary template}}
- A<0, 0, int, int, 0> a;
+ template<int N, typename T, typename U, T V> struct A<0, N, T, U, V>; // expected-note {{matches}}
+ // FIXME: It appears that this partial specialization should be ill-formed as
+ // it is not more specialized than the primary template. V is not deducible
+ // because it does not have the same type as the corresponding parameter.
+ template<int N, typename T, typename U, U V> struct A<0, N, T, U, V> {}; // expected-note {{matches}}
+ A<0, 0, int, int, 0> a; // expected-error {{ambiguous}}
}
namespace partial_order_references {
@@ -457,24 +458,13 @@ namespace dependent_nested_partial_specialization {
namespace nondependent_default_arg_ordering {
int n, m;
template<typename A, A B = &n> struct X {};
-
template<typename A> void f(X<A>);
- // expected-note at -1 {{candidate function}}
template<typename A> void f(X<A, &m>);
- // expected-note at -1 {{candidate function}}
template<typename A, A B> void f(X<A, B>);
- // expected-note at -1 2{{candidate function}}
template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>);
- // expected-note at -1 2{{candidate function}}
-
- // FIXME: When partial ordering, we get an inconsistent deduction between
- // `A` (type-parameter-0-0) and `int *`, when deducing the first parameter.
- // The deduction mechanism needs to be extended to be able to correctly
- // handle these cases where the argument's template parameters appear in
- // the result.
void g() {
- X<int *, &n> x; f(x); // expected-error {{call to 'f' is ambiguous}}
- X<int *, &m> y; f(y); // expected-error {{call to 'f' is ambiguous}}
+ X<int *, &n> x; f(x);
+ X<int *, &m> y; f(y);
}
}
diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp
index 9908af5e78669d..a7236669276aa3 100644
--- a/clang/test/SemaTemplate/temp_arg_template.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template.cpp
@@ -1,40 +1,33 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
-template<template<typename T> class X> struct A; // #A
-// expected-note at -1 2{{previous template template parameter is here}}
+template<template<typename T> class X> struct A; // expected-note 2{{previous template template parameter is here}}
template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
-template<template<int I> class X> struct C;
-// precxx17-error at -1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int' vs 'const int &')}}
-// cxx17-error at -2 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
-// expected-note at -3 {{previous template template parameter is here}}
+template<template<int I> class X> struct C; // expected-note {{previous non-type template parameter with type 'int' is here}}
-template<class> struct X; // expected-note {{template is declared here}}
-template<int N> struct Y; // expected-note {{template parameter is declared here}}
+template<class> struct X; // expected-note{{too few template parameters in template template argument}}
+template<int N> struct Y; // expected-note{{template parameter has a
diff erent kind in template argument}}
template<long N> struct Ylong;
-template<const int &N> struct Yref; // precxx17-note {{template parameter is declared here}}
+template<const int &N> struct Yref; // expected-note{{template non-type parameter has a
diff erent type 'const int &' in template argument}}
namespace N {
template<class> struct Z;
}
-template<class, class> struct TooMany; // expected-note{{template is declared here}}
+template<class, class> struct TooMany; // expected-note{{too many template parameters in template template argument}}
A<X> *a1;
A<N::Z> *a2;
A< ::N::Z> *a3;
-A<Y> *a4; // expected-error@#A {{template argument for non-type template parameter must be an expression}}
- // expected-note at -1 {{
diff erent template parameters}}
-A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}}
- // expected-note at -1 {{
diff erent template parameters}}
-B<X> *a6; // expected-error {{too many template arguments for class template 'X'}}
- // expected-note at -1 {{
diff erent template parameters}}
+A<Y> *a4; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
+A<TooMany> *a5; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
+B<X> *a6; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
C<Y> *a7;
C<Ylong> *a8;
-C<Yref> *a9; // expected-note {{
diff erent template parameters}}
+C<Yref> *a9; // expected-error{{template template argument has
diff erent template parameters than its corresponding template template parameter}}
template<typename T> void f(int);
@@ -110,9 +103,9 @@ void foo() {
namespace CheckDependentNonTypeParamTypes {
template<template<typename T, typename U, T v> class X> struct A {
- // expected-note at -1 {{previous template template parameter is here}}
void f() {
- X<int, void*, 3> x;
+ X<int, void*, 3> x; // precxx17-error {{does not refer to any declaration}} \
+ cxx17-error {{value of type 'int' is not implicitly convertible to 'void *'}}
}
void g() {
X<int, long, 3> x;
@@ -131,16 +124,15 @@ namespace CheckDependentNonTypeParamTypes {
}
};
- template<typename T, typename U, U v> struct B {
- // expected-error at -1 {{conflicting deduction 'U' against 'T' for parameter}}
+ template<typename T, typename U, U v> struct B { // precxx17-note {{parameter}}
static const U value = v;
};
// FIXME: This should probably be rejected, but the rules are at best unclear.
- A<B> ab; // expected-note {{
diff erent template parameters}}
+ A<B> ab;
void use() {
- ab.f();
+ ab.f(); // expected-note {{instantiation of}}
ab.g();
ab.h();
}
diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
index 441b9e5af9d3d7..6f6568b9ab7764 100644
--- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
@@ -1,16 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
-// expected-note at temp_arg_template_p0522.cpp:* 1+{{template is declared here}}
-// expected-note at temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}}
-// expected-note at temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}}
+// expected-note at temp_arg_template_p0522.cpp:* 1+{{}}
-template<template<int> typename> struct Ti; // #Ti
-template<template<int...> typename> struct TPi; // #TPi
+template<template<int> typename> struct Ti;
+template<template<int...> typename> struct TPi;
template<template<int, int...> typename> struct TiPi;
template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed?
-template<typename T, template<T> typename> struct tT0; // #tT0
-template<template<typename T, T> typename> struct Tt0; // #Tt0
+template<typename T, template<T> typename> struct tT0;
+template<template<typename T, T> typename> struct Tt0;
template<template<typename> typename> struct Tt;
template<template<typename, typename...> typename> struct TtPt;
@@ -22,7 +20,7 @@ template<int...> struct Pi;
template<int, int, int...> struct iiPi;
template<int, typename = int> struct iDt;
-template<int, typename> struct it; // #it
+template<int, typename> struct it;
template<typename T, T v> struct t0;
@@ -33,14 +31,10 @@ namespace IntParam {
Ti<iDi>,
Ti<Pi>,
Ti<iDt>>;
- using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ using err1 = Ti<ii>; // expected-error {{
diff erent template parameters}}
+ using err2 = Ti<iiPi>; // expected-error {{
diff erent template parameters}}
+ using err3 = Ti<t0>; // expected-error {{
diff erent template parameters}}
+ using err4 = Ti<it>; // expected-error {{
diff erent template parameters}}
}
// These are accepted by the backwards-compatibility "parameter pack in
@@ -48,12 +42,9 @@ namespace IntParam {
namespace IntPackParam {
using ok = TPi<Pi>;
using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
- using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note at -1 {{
diff erent template parameters}}
+ using err1 = TPi<t0>; // expected-error {{
diff erent template parameters}}
+ using err2 = TPi<iDt>; // expected-error {{
diff erent template parameters}}
+ using err3 = TPi<it>; // expected-error {{
diff erent template parameters}}
}
namespace IntAndPackParam {
@@ -64,50 +55,42 @@ namespace IntAndPackParam {
namespace DependentType {
using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
- using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ using err1 = tT0<int, ii>; // expected-error {{
diff erent template parameters}}
using err2 = tT0<short, i>; // FIXME: should this be OK?
using err2a = tT0<long long, i>; // FIXME: should this be OK (if long long is larger than int)?
- using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}}
- // expected-note at -1 {{
diff erent template parameters}}
- using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}}
- // expected-note at -1 {{
diff erent template parameters}}
+ using err2b = tT0<void*, i>; // expected-error {{
diff erent template parameters}}
+ using err3 = tT0<short, t0>; // expected-error {{
diff erent template parameters}}
using ok2 = Tt0<t0>;
- using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}}
- // expected-note at -1 {{
diff erent template parameters}}
+ using err4 = Tt0<it>; // expected-error {{
diff erent template parameters}}
}
namespace Auto {
- template<template<int> typename T> struct TInt {}; // #TInt
- template<template<int*> typename T> struct TIntPtr {}; // #TIntPtr
+ template<template<int> typename T> struct TInt {};
+ template<template<int*> typename T> struct TIntPtr {};
template<template<auto> typename T> struct TAuto {};
template<template<auto*> typename T> struct TAutoPtr {};
template<template<decltype(auto)> typename T> struct TDecltypeAuto {};
template<auto> struct Auto;
- template<auto*> struct AutoPtr; // #AutoPtr
+ template<auto*> struct AutoPtr;
template<decltype(auto)> struct DecltypeAuto;
template<int> struct Int;
template<int*> struct IntPtr;
TInt<Auto> ia;
- TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ TInt<AutoPtr> iap; // FIXME: ill-formed (?)
TInt<DecltypeAuto> ida;
TInt<Int> ii;
- TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}}
- // expected-note at -1 {{
diff erent template parameters}}
+ TInt<IntPtr> iip; // expected-error {{
diff erent template parameters}}
TIntPtr<Auto> ipa;
TIntPtr<AutoPtr> ipap;
TIntPtr<DecltypeAuto> ipda;
- TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ TIntPtr<Int> ipi; // expected-error {{
diff erent template parameters}}
TIntPtr<IntPtr> ipip;
TAuto<Auto> aa;
- TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ TAuto<AutoPtr> aap; // FIXME: ill-formed (?)
TAuto<Int> ai; // FIXME: ill-formed (?)
TAuto<IntPtr> aip; // FIXME: ill-formed (?)
@@ -128,8 +111,7 @@ namespace Auto {
// parameters (such as 'user-defined-type &') that are not valid 'auto'
// parameters.
TDecltypeAuto<Auto> daa;
- TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}}
- // expected-note at -1 {{
diff erent template parameters}}
+ TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed
int n;
template<auto A, decltype(A) B = &n> struct SubstFailure;
@@ -146,7 +128,7 @@ namespace GH62529 {
} // namespace GH62529
namespace GH101394 {
- struct X {}; // #X
+ struct X {};
struct Y {
constexpr Y(const X &) {}
};
@@ -157,12 +139,8 @@ namespace GH101394 {
template struct A<B>;
} // namespace t1
namespace t2 {
- template<template<Y> class> struct A {}; // #A
- template<X> struct B; // #B
- template struct A<B>;
- // expected-error@#A {{no viable conversion from 'const Y' to 'X'}}
- // expected-note at -2 {{
diff erent template parameters}}
- // expected-note@#X 2{{not viable}}
- // expected-note@#B {{passing argument to parameter here}}
+ template<template<Y> class> struct A {};
+ template<X> struct B;
+ template struct A<B>; // expected-error {{
diff erent template parameters}}
} // namespace t2
} // namespace GH101394
diff --git a/clang/test/Templight/templight-empty-entries-fix.cpp b/clang/test/Templight/templight-empty-entries-fix.cpp
index d13b748068efec..e17be9012e59cc 100644
--- a/clang/test/Templight/templight-empty-entries-fix.cpp
+++ b/clang/test/Templight/templight-empty-entries-fix.cpp
@@ -314,18 +314,6 @@ void foo() {
// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
// CHECK: {{^poi:[ ]+''$}}
// CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
-// CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
-// CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}}
-// CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
-// CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
-// CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}}
-// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+d$}}
// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
// CHECK: {{^event:[ ]+End$}}
diff --git a/clang/test/Templight/templight-prior-template-arg.cpp b/clang/test/Templight/templight-prior-template-arg.cpp
index 14bcb6a4d48f6b..e9b1dd47bb603a 100644
--- a/clang/test/Templight/templight-prior-template-arg.cpp
+++ b/clang/test/Templight/templight-prior-template-arg.cpp
@@ -10,76 +10,63 @@ class B {};
// CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
// CHECK: {{^event:[ ]+Begin$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:1'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}}
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B::Outer'$}}
// CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
// CHECK: {{^event:[ ]+End$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:1'$}}
-//
-// CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'B::Outer'$}}
-// CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
-// CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:3'$}}
-// CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'B::Outer'$}}
-// CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
-// CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}}
//
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
// CHECK: {{^event:[ ]+Begin$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
// CHECK: {{^event:[ ]+End$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
//
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
// CHECK: {{^event:[ ]+Begin$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
// CHECK: {{^event:[ ]+End$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
//
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+Memoization$}}
// CHECK: {{^event:[ ]+Begin$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+Memoization$}}
// CHECK: {{^event:[ ]+End$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
//
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+Memoization$}}
// CHECK: {{^event:[ ]+Begin$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
// CHECK-LABEL: {{^---$}}
// CHECK: {{^name:[ ]+'B<A>'$}}
// CHECK: {{^kind:[ ]+Memoization$}}
// CHECK: {{^event:[ ]+End$}}
// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
-// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
B<A> b;
diff --git a/libcxx/test/libcxx/type_traits/is_specialization.verify.cpp b/libcxx/test/libcxx/type_traits/is_specialization.verify.cpp
index a2ea8efcbe5de6..3593c2e095db91 100644
--- a/libcxx/test/libcxx/type_traits/is_specialization.verify.cpp
+++ b/libcxx/test/libcxx/type_traits/is_specialization.verify.cpp
@@ -17,5 +17,5 @@
#include <array>
#include <utility>
-// expected-error-re@*:* {{{{must be an expression|
diff erent template parameters}}}}
+// expected-error-re@*:* {{{{could not match _Size against 'type-parameter-0-0'|
diff erent template parameters}}}}
static_assert(!std::__is_specialization_v<std::pair<int, std::size_t>, std::array>);
More information about the cfe-commits
mailing list