Skip to content

Commit ada6372

Browse files
committed
Revert "[clang] Finish implementation of P0522 (#96023)"
This caused Clang to reject valid code, see discussion on the PR #96023 (comment) and #111363 This reverts commit 6afe567 and follow-up commit 9abb97f.
1 parent 3be6916 commit ada6372

File tree

19 files changed

+277
-681
lines changed

19 files changed

+277
-681
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,6 @@ C++23 Feature Support
174174
C++20 Feature Support
175175
^^^^^^^^^^^^^^^^^^^^^
176176

177-
C++17 Feature Support
178-
^^^^^^^^^^^^^^^^^^^^^
179-
- The implementation of the relaxed template template argument matching rules is
180-
more complete and reliable, and should provide more accurate diagnostics.
181177

182178
Resolutions to C++ Defect Reports
183179
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -335,10 +331,6 @@ Improvements to Clang's diagnostics
335331

336332
- Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391.
337333

338-
- Clang now properly explains the reason a template template argument failed to
339-
match a template template parameter, in terms of the C++17 relaxed matching rules
340-
instead of the old ones.
341-
342334
- Don't emit duplicated dangling diagnostics. (#GH93386).
343335

344336
- Improved diagnostic when trying to befriend a concept. (#GH45182).
@@ -444,8 +436,6 @@ Bug Fixes to C++ Support
444436
- Correctly check constraints of explicit instantiations of member functions. (#GH46029)
445437
- When performing partial ordering of function templates, clang now checks that
446438
the deduction was consistent. Fixes (#GH18291).
447-
- Fixes to several issues in partial ordering of template template parameters, which
448-
were documented in the test suite.
449439
- Fixed an assertion failure about a constraint of a friend function template references to a value with greater
450440
template depth than the friend function template. (#GH98258)
451441
- Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,13 +5262,6 @@ def note_template_arg_refers_here_func : Note<
52625262
def err_template_arg_template_params_mismatch : Error<
52635263
"template template argument has different template parameters than its "
52645264
"corresponding template template parameter">;
5265-
def note_template_arg_template_params_mismatch : Note<
5266-
"template template argument has different template parameters than its "
5267-
"corresponding template template parameter">;
5268-
def err_non_deduced_mismatch : Error<
5269-
"could not match %diff{$ against $|types}0,1">;
5270-
def err_inconsistent_deduction : Error<
5271-
"conflicting deduction %diff{$ against $|types}0,1 for parameter">;
52725265
def err_template_arg_not_integral_or_enumeral : Error<
52735266
"non-type template argument of type %0 must have an integral or enumeration"
52745267
" type">;

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12417,9 +12417,8 @@ class Sema final : public SemaBase {
1241712417
sema::TemplateDeductionInfo &Info);
1241812418

1241912419
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(
12420-
TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg,
12421-
const DefaultArguments &DefaultArgs, SourceLocation ArgLoc,
12422-
bool IsDeduced);
12420+
TemplateParameterList *PParam, TemplateDecl *AArg,
12421+
const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced);
1242312422

1242412423
/// Mark which template parameters are used in a given expression.
1242512424
///
@@ -12728,9 +12727,6 @@ class Sema final : public SemaBase {
1272812727

1272912728
/// We are instantiating a type alias template declaration.
1273012729
TypeAliasTemplateInstantiation,
12731-
12732-
/// We are performing partial ordering for template template parameters.
12733-
PartialOrderingTTP,
1273412730
} Kind;
1273512731

1273612732
/// Was the enclosing context a non-instantiation SFINAE context?
@@ -12952,12 +12948,6 @@ class Sema final : public SemaBase {
1295212948
TemplateDecl *Entity, BuildingDeductionGuidesTag,
1295312949
SourceRange InstantiationRange = SourceRange());
1295412950

12955-
struct PartialOrderingTTP {};
12956-
/// \brief Note that we are partial ordering template template parameters.
12957-
InstantiatingTemplate(Sema &SemaRef, SourceLocation ArgLoc,
12958-
PartialOrderingTTP, TemplateDecl *PArg,
12959-
SourceRange InstantiationRange = SourceRange());
12960-
1296112951
/// Note that we have finished instantiating this template.
1296212952
void Clear();
1296312953

clang/lib/Frontend/FrontendActions.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,6 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
457457
return "BuildingDeductionGuides";
458458
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
459459
return "TypeAliasTemplateInstantiation";
460-
case CodeSynthesisContext::PartialOrderingTTP:
461-
return "PartialOrderingTTP";
462460
}
463461
return "";
464462
}

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5498,7 +5498,8 @@ bool Sema::CheckTemplateArgumentList(
54985498
DefaultArgs && ParamIdx >= DefaultArgs.StartPos) {
54995499
// All written arguments should have been consumed by this point.
55005500
assert(ArgIdx == NumArgs && "bad default argument deduction");
5501-
if (ParamIdx == DefaultArgs.StartPos) {
5501+
// FIXME: Don't ignore parameter packs.
5502+
if (ParamIdx == DefaultArgs.StartPos && !(*Param)->isParameterPack()) {
55025503
assert(Param + DefaultArgs.Args.size() <= ParamEnd);
55035504
// Default arguments from a DeducedTemplateName are already converted.
55045505
for (const TemplateArgument &DefArg : DefaultArgs.Args) {
@@ -5575,6 +5576,9 @@ bool Sema::CheckTemplateArgumentList(
55755576
return true;
55765577
}
55775578

5579+
// We're now done with this argument.
5580+
++ArgIdx;
5581+
55785582
if ((*Param)->isTemplateParameterPack()) {
55795583
// The template parameter was a template parameter pack, so take the
55805584
// deduced argument and place it on the argument pack. Note that we
@@ -5585,19 +5589,8 @@ bool Sema::CheckTemplateArgumentList(
55855589
} else {
55865590
// Move to the next template parameter.
55875591
++Param;
5588-
if (PartialOrderingTTP && PackExpansionIntoNonPack) {
5589-
// Keep converting the pattern in the argument against
5590-
// subsequent parameters. The argument is converted
5591-
// in place and will be added back when we are done.
5592-
SugaredConverted.pop_back();
5593-
CanonicalConverted.pop_back();
5594-
continue;
5595-
}
55965592
}
55975593

5598-
// We're now done with this argument.
5599-
++ArgIdx;
5600-
56015594
// If we just saw a pack expansion into a non-pack, then directly convert
56025595
// the remaining arguments, because we don't know what parameters they'll
56035596
// match up with.
@@ -5731,10 +5724,14 @@ bool Sema::CheckTemplateArgumentList(
57315724
// pack expansions; they might be empty. This can happen even if
57325725
// PartialTemplateArgs is false (the list of arguments is complete but
57335726
// still dependent).
5734-
while (ArgIdx < NumArgs && NewArgs[ArgIdx].getArgument().isPackExpansion()) {
5735-
const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument();
5736-
SugaredConverted.push_back(Arg);
5737-
CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
5727+
if (ArgIdx < NumArgs && CurrentInstantiationScope &&
5728+
CurrentInstantiationScope->getPartiallySubstitutedPack()) {
5729+
while (ArgIdx < NumArgs &&
5730+
NewArgs[ArgIdx].getArgument().isPackExpansion()) {
5731+
const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument();
5732+
SugaredConverted.push_back(Arg);
5733+
CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
5734+
}
57385735
}
57395736

57405737
// If we have any leftover arguments, then there were too many arguments.
@@ -7324,46 +7321,64 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
73247321
<< Template;
73257322
}
73267323

7327-
if (!getLangOpts().RelaxedTemplateTemplateArgs)
7328-
return !TemplateParameterListsAreEqual(
7329-
Template->getTemplateParameters(), Params, /*Complain=*/true,
7330-
TPL_TemplateTemplateArgumentMatch, Arg.getLocation());
7331-
73327324
// C++1z [temp.arg.template]p3: (DR 150)
73337325
// A template-argument matches a template template-parameter P when P
73347326
// is at least as specialized as the template-argument A.
7335-
if (!isTemplateTemplateParameterAtLeastAsSpecializedAs(
7336-
Params, Param, Template, DefaultArgs, Arg.getLocation(), IsDeduced))
7337-
return true;
7338-
// P2113
7339-
// C++20[temp.func.order]p2
7340-
// [...] If both deductions succeed, the partial ordering selects the
7341-
// more constrained template (if one exists) as determined below.
7342-
SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
7343-
Params->getAssociatedConstraints(ParamsAC);
7344-
// C++20[temp.arg.template]p3
7345-
// [...] In this comparison, if P is unconstrained, the constraints on A
7346-
// are not considered.
7347-
if (ParamsAC.empty())
7348-
return false;
7327+
if (getLangOpts().RelaxedTemplateTemplateArgs) {
7328+
// Quick check for the common case:
7329+
// If P contains a parameter pack, then A [...] matches P if each of A's
7330+
// template parameters matches the corresponding template parameter in
7331+
// the template-parameter-list of P.
7332+
if (TemplateParameterListsAreEqual(
7333+
Template->getTemplateParameters(), Params, false,
7334+
TPL_TemplateTemplateArgumentMatch, Arg.getLocation()) &&
7335+
// If the argument has no associated constraints, then the parameter is
7336+
// definitely at least as specialized as the argument.
7337+
// Otherwise - we need a more thorough check.
7338+
!Template->hasAssociatedConstraints())
7339+
return false;
73497340

7350-
Template->getAssociatedConstraints(TemplateAC);
7341+
if (isTemplateTemplateParameterAtLeastAsSpecializedAs(
7342+
Params, Template, DefaultArgs, Arg.getLocation(), IsDeduced)) {
7343+
// P2113
7344+
// C++20[temp.func.order]p2
7345+
// [...] If both deductions succeed, the partial ordering selects the
7346+
// more constrained template (if one exists) as determined below.
7347+
SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
7348+
Params->getAssociatedConstraints(ParamsAC);
7349+
// C++2a[temp.arg.template]p3
7350+
// [...] In this comparison, if P is unconstrained, the constraints on A
7351+
// are not considered.
7352+
if (ParamsAC.empty())
7353+
return false;
73517354

7352-
bool IsParamAtLeastAsConstrained;
7353-
if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
7354-
IsParamAtLeastAsConstrained))
7355-
return true;
7356-
if (!IsParamAtLeastAsConstrained) {
7357-
Diag(Arg.getLocation(),
7358-
diag::err_template_template_parameter_not_at_least_as_constrained)
7359-
<< Template << Param << Arg.getSourceRange();
7360-
Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
7361-
Diag(Template->getLocation(), diag::note_entity_declared_at) << Template;
7362-
MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
7363-
TemplateAC);
7364-
return true;
7355+
Template->getAssociatedConstraints(TemplateAC);
7356+
7357+
bool IsParamAtLeastAsConstrained;
7358+
if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
7359+
IsParamAtLeastAsConstrained))
7360+
return true;
7361+
if (!IsParamAtLeastAsConstrained) {
7362+
Diag(Arg.getLocation(),
7363+
diag::err_template_template_parameter_not_at_least_as_constrained)
7364+
<< Template << Param << Arg.getSourceRange();
7365+
Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
7366+
Diag(Template->getLocation(), diag::note_entity_declared_at)
7367+
<< Template;
7368+
MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
7369+
TemplateAC);
7370+
return true;
7371+
}
7372+
return false;
7373+
}
7374+
// FIXME: Produce better diagnostics for deduction failures.
73657375
}
7366-
return false;
7376+
7377+
return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
7378+
Params,
7379+
true,
7380+
TPL_TemplateTemplateArgumentMatch,
7381+
Arg.getLocation());
73677382
}
73687383

73697384
static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl,

0 commit comments

Comments
 (0)