Skip to content

[clang] Template argument expressions are not full expressions for the purposes of unexpanded packs #58679

Closed
@mizvekov

Description

@mizvekov

Repro: https://godbolt.org/z/rn8e3GP6c

template <class> constexpr int A = 1;

template <int> struct B;
template <> struct B<1> { using b1 = void; };

template <class> using C = char;

template <class... Ds> int D{ B<A<C<Ds>>>{}... };

The pattern contains an unexpanded pack, but it's just syntatic.
We incorrectly don't convert the expression, leaving it as a instantiation dependent DeclRef, and then
incorrectly specialize the primary template for B.

This is diagnosed with:

<source>:8:31: error: implicit instantiation of undefined template 'B<A<C<Ds>>>'
template <class... Ds> int D{ B<A<C<Ds>>>{}... };
                              ^
<source>:3:23: note: template is declared here
template <int> struct B;
                      ^
<source>:8:44: error: pack expansion does not contain any unexpanded parameter packs
template <class... Ds> int D{ B<A<C<Ds>>>{}... };

With recent changes (https://reviews.llvm.org/D136564) regarding sugared substitution of default template arguments, we would start misdiagnosing this snippet as well (continued from above):

struct E {
  template <class E1, class = typename B<A<E1>>::b1> E(E1);
};

template <typename... Es> int F{ E(C<Es>{})... };

And this is diagnosed with:

<source>:14:34: error: no matching conversion for functional-style cast from 'C<Es>' (aka 'char') to 'E'
template <typename... Es> int F{ E(C<Es>{})... };
                                 ^~~~~~~~~
<source>:10:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'C<Es>' (aka 'char') to 'const E' for 1st argument
struct E {
       ^
<source>:10:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'C<Es>' (aka 'char') to 'E' for 1st argument
struct E {
       ^
<source>:11:54: note: candidate template ignored: substitution failure [with E1 = C<Es>]: implicit instantiation of undefined template 'B<A<C<Ds>>>'
  template <class E1, class = typename B<A<E1>>::b1> E(E1);

Metadata

Metadata

Assignees

Labels

clang:frontendLanguage frontend issues, e.g. anything involving "Sema"rejects-valid

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions