Skip to content

Commit 06b9c19

Browse files
committed
[clang] Allow pack expansions when partial ordering against template template parameters
When partial ordering alias templates against template template parameters, allow pack expansions when the alias has a fixed-size parameter list. These expansions were generally disallowed by proposed resolution for CWG1430. By previously diagnosing these when checking template template parameters, we would be too strict in trying to prevent any potential invalid use. This flows against the more general idea that template template parameters are weakly typed, that we would rather allow an argument that might be possibly misused, and only diagnose the actual misuses during instantiation. Since this interaction between P0522R0 and CWG1430 is also a backwards-compat breaking change, we implement provisional wording to allow these. Fixes #62529
1 parent 1066eb5 commit 06b9c19

File tree

5 files changed

+32
-8
lines changed

5 files changed

+32
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,8 @@ Bug Fixes to C++ Support
708708
expression.
709709
- Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361).
710710
- Correctly treat the compound statement of an ``if consteval`` as an immediate context. Fixes (#GH91509).
711+
- When partial ordering alias templates against template template parameters,
712+
allow pack expansions when the alias has a fixed-size parameter list. Fixes (#GH62529).
711713

712714
Bug Fixes to AST Handling
713715
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9216,14 +9216,20 @@ class Sema final : public SemaBase {
92169216
/// receive true if the cause for the error is the associated constraints of
92179217
/// the template not being satisfied by the template arguments.
92189218
///
9219+
/// \param PartialOrderingTTP If true, assume these template arguments are
9220+
/// the injected template arguments for a template template parameter.
9221+
/// This will relax the requirement that all its possible uses are valid:
9222+
/// TTP checking is loose, and assumes that invalid uses will be diagnosed
9223+
/// during instantiation.
9224+
///
92199225
/// \returns true if an error occurred, false otherwise.
92209226
bool CheckTemplateArgumentList(
92219227
TemplateDecl *Template, SourceLocation TemplateLoc,
92229228
TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
92239229
SmallVectorImpl<TemplateArgument> &SugaredConverted,
92249230
SmallVectorImpl<TemplateArgument> &CanonicalConverted,
92259231
bool UpdateArgsWithConversions = true,
9226-
bool *ConstraintsNotSatisfied = nullptr);
9232+
bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false);
92279233

92289234
bool CheckTemplateTypeArgument(
92299235
TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6556,7 +6556,8 @@ bool Sema::CheckTemplateArgumentList(
65566556
TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
65576557
SmallVectorImpl<TemplateArgument> &SugaredConverted,
65586558
SmallVectorImpl<TemplateArgument> &CanonicalConverted,
6559-
bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied) {
6559+
bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied,
6560+
bool PartialOrderingTTP) {
65606561

65616562
if (ConstraintsNotSatisfied)
65626563
*ConstraintsNotSatisfied = false;
@@ -6627,9 +6628,14 @@ bool Sema::CheckTemplateArgumentList(
66276628
bool PackExpansionIntoNonPack =
66286629
NewArgs[ArgIdx].getArgument().isPackExpansion() &&
66296630
(!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param));
6630-
if (PackExpansionIntoNonPack && (isa<TypeAliasTemplateDecl>(Template) ||
6631-
isa<ConceptDecl>(Template))) {
6632-
// Core issue 1430: we have a pack expansion as an argument to an
6631+
// CWG1430: Don't diagnose this pack expansion when partial
6632+
// ordering template template parameters. Some uses of the template could
6633+
// be valid, and invalid uses will be diagnosed later during
6634+
// instantiation.
6635+
if (PackExpansionIntoNonPack && !PartialOrderingTTP &&
6636+
(isa<TypeAliasTemplateDecl>(Template) ||
6637+
isa<ConceptDecl>(Template))) {
6638+
// CWG1430: we have a pack expansion as an argument to an
66336639
// alias template, and it's not part of a parameter pack. This
66346640
// can't be canonicalized, so reject it now.
66356641
// As for concepts - we cannot normalize constraints where this

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6243,7 +6243,9 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
62436243
// specialized as A.
62446244
SmallVector<TemplateArgument, 4> SugaredPArgs;
62456245
if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, SugaredPArgs,
6246-
PArgs) ||
6246+
PArgs, /*UpdateArgsWithConversions=*/true,
6247+
/*ConstraintsNotSatisfied=*/nullptr,
6248+
/*PartialOrderTTP=*/true) ||
62476249
Trap.hasErrorOccurred())
62486250
return false;
62496251
}

clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp renamed to clang/test/SemaTemplate/temp_arg_template_p0522.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
22

3-
// expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}}
3+
// expected-note@temp_arg_template_p0522.cpp:* 1+{{}}
44

55
template<template<int> typename> struct Ti;
66
template<template<int...> typename> struct TPi;
@@ -118,3 +118,11 @@ namespace Auto {
118118
TInt<SubstFailure> isf; // FIXME: this should be ill-formed
119119
TIntPtr<SubstFailure> ipsf;
120120
}
121+
122+
namespace GH62529 {
123+
// Note: the constraint here is just for bypassing a fast-path.
124+
template<class T1> requires(true) using A = int;
125+
template<template<class ...T2s> class TT1, class T3> struct B {};
126+
template<class T4> B<A, T4> f();
127+
auto t = f<int>();
128+
} // namespace GH62529

0 commit comments

Comments
 (0)