Skip to content

[clang] Allow pack expansions when partial ordering against template template parameters #91833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading