Skip to content
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

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

Closed
mizvekov opened this issue Oct 28, 2022 · 1 comment
Assignees
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid

Comments

@mizvekov
Copy link
Contributor

mizvekov commented Oct 28, 2022

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);
@mizvekov mizvekov added clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid labels Oct 28, 2022
@mizvekov mizvekov self-assigned this Oct 28, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 28, 2022

@llvm/issue-subscribers-clang-frontend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid
Projects
None yet
Development

No branches or pull requests

2 participants