Skip to content

Commit

Permalink
[clang] Allow pack expansions when partial ordering against template …
Browse files Browse the repository at this point in the history
…template parameters (#91833)

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
  • Loading branch information
mizvekov committed May 13, 2024
1 parent 0f79066 commit b8f802f
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 8 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,8 @@ Bug Fixes to C++ Support
expression.
- Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361).
- Correctly treat the compound statement of an ``if consteval`` as an immediate context. Fixes (#GH91509).
- When partial ordering alias templates against template template parameters,
allow pack expansions when the alias has a fixed-size parameter list. Fixes (#GH62529).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -9216,14 +9216,20 @@ class Sema final : public SemaBase {
/// receive true if the cause for the error is the associated constraints of
/// the template not being satisfied by the template arguments.
///
/// \param PartialOrderingTTP If true, assume these template arguments are
/// the injected template arguments for a template template parameter.
/// This will relax the requirement that all its possible uses are valid:
/// TTP checking is loose, and assumes that invalid uses will be diagnosed
/// during instantiation.
///
/// \returns true if an error occurred, false otherwise.
bool CheckTemplateArgumentList(
TemplateDecl *Template, SourceLocation TemplateLoc,
TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
SmallVectorImpl<TemplateArgument> &SugaredConverted,
SmallVectorImpl<TemplateArgument> &CanonicalConverted,
bool UpdateArgsWithConversions = true,
bool *ConstraintsNotSatisfied = nullptr);
bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false);

bool CheckTemplateTypeArgument(
TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
Expand Down
14 changes: 10 additions & 4 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6556,7 +6556,8 @@ bool Sema::CheckTemplateArgumentList(
TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
SmallVectorImpl<TemplateArgument> &SugaredConverted,
SmallVectorImpl<TemplateArgument> &CanonicalConverted,
bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied) {
bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied,
bool PartialOrderingTTP) {

if (ConstraintsNotSatisfied)
*ConstraintsNotSatisfied = false;
Expand Down Expand Up @@ -6627,9 +6628,14 @@ bool Sema::CheckTemplateArgumentList(
bool PackExpansionIntoNonPack =
NewArgs[ArgIdx].getArgument().isPackExpansion() &&
(!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param));
if (PackExpansionIntoNonPack && (isa<TypeAliasTemplateDecl>(Template) ||
isa<ConceptDecl>(Template))) {
// Core issue 1430: we have a pack expansion as an argument to an
// CWG1430: Don't diagnose this pack expansion when partial
// ordering template template parameters. Some uses of the template could
// be valid, and invalid uses will be diagnosed later during
// instantiation.
if (PackExpansionIntoNonPack && !PartialOrderingTTP &&
(isa<TypeAliasTemplateDecl>(Template) ||
isa<ConceptDecl>(Template))) {
// CWG1430: we have a pack expansion as an argument to an
// alias template, and it's not part of a parameter pack. This
// can't be canonicalized, so reject it now.
// As for concepts - we cannot normalize constraints where this
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6243,7 +6243,9 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
// specialized as A.
SmallVector<TemplateArgument, 4> SugaredPArgs;
if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, SugaredPArgs,
PArgs) ||
PArgs, /*UpdateArgsWithConversions=*/true,
/*ConstraintsNotSatisfied=*/nullptr,
/*PartialOrderTTP=*/true) ||
Trap.hasErrorOccurred())
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s

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

template<template<int> typename> struct Ti;
template<template<int...> typename> struct TPi;
Expand Down Expand Up @@ -118,3 +118,11 @@ namespace Auto {
TInt<SubstFailure> isf; // FIXME: this should be ill-formed
TIntPtr<SubstFailure> ipsf;
}

namespace GH62529 {
// Note: the constraint here is just for bypassing a fast-path.
template<class T1> requires(true) using A = int;
template<template<class ...T2s> class TT1, class T3> struct B {};
template<class T4> B<A, T4> f();
auto t = f<int>();
} // namespace GH62529

0 comments on commit b8f802f

Please sign in to comment.