Skip to content

Regression in clang 16 -frelaxed-template-template-args support to alias templates. #63281

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

Open
mawww opened this issue Jun 13, 2023 · 6 comments
Assignees
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@mawww
Copy link

mawww commented Jun 13, 2023

template<typename T, int I = 0>
struct A {};

template<typename T, int I = 0>
using B = A<T, I>; 

template<template <typename> typename T>
void g() {}

void f() {
    g<A>();
    g<B>();
}

fails to compile on Clang 16 (using -frelaxed-template-template-args) with the following error:

<source>:12:5: error: no matching function for call to 'g'
    g<B>();
    ^~~~
<source>:8:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T'
void g() {}
     ^

The same code compiles on Clang 15. Removing -frelaxed-template-template-args makes that code fail in both Clang 15 and 16 and also complains about g<A>() with the same error.

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Jun 13, 2023
@llvmbot
Copy link
Member

llvmbot commented Jun 13, 2023

@llvm/issue-subscribers-clang-frontend

@krobelus
Copy link
Member

bisects to ef8feb6..f4ea3bd (using manyclangs)
probably introduced by f4ea3bd, cc @mizvekov

@aThorp96
Copy link

This appears to affect Apple's clang 15 as well. Is this the right place for that report?

 ~/code/cpp_test [04:36:12]
athorp$ cat test.cpp
template<typename T, int I = 0>
struct A {};

template<typename T, int I = 0>
using B = A<T, I>;

template<template <typename> typename T>
void g() {}

void f() {
    g<A>();
    g<B>();
}%
 ~/code/cpp_test [04:36:14]
athorp$ c++ --version
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
 ~/code/cpp_test [04:36:21]
athorp$ c++ -Wc++11-extensions test.cpp
test.cpp:5:11: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
using B = A<T, I>;
          ^
test.cpp:7:30: warning: template template parameter using 'typename' is a C++17 extension [-Wc++17-extensions]
template<template <typename> typename T>
                             ^~~~~~~~
                             class
test.cpp:11:5: error: no matching function for call to 'g'
    g<A>();
    ^~~~
test.cpp:8:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T'
void g() {}
     ^
test.cpp:12:5: error: no matching function for call to 'g'
    g<B>();
    ^~~~
test.cpp:8:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T'
void g() {}
     ^
2 warnings and 2 errors generated.
 ~/code/cpp_test [04:36:31]
athorp$ c++ -frelaxed-template-template-args -Wc++11-extensions test.cpp
test.cpp:5:11: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
using B = A<T, I>;
          ^
test.cpp:7:30: warning: template template parameter using 'typename' is a C++17 extension [-Wc++17-extensions]
template<template <typename> typename T>
                             ^~~~~~~~
                             class
test.cpp:12:5: error: no matching function for call to 'g'
    g<B>();
    ^~~~
test.cpp:8:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'T'
void g() {}
     ^
2 warnings and 1 error generated.

@mizvekov
Copy link
Contributor

Note that this didn't work in clang-15 properly either: https://godbolt.org/z/GbcEvW1cM

Notice the previously incorrect deduction, which would produce a different instantiation, and so failing to diagnose the duplicate explicit instantiation.

@mizvekov
Copy link
Contributor

mizvekov commented Apr 28, 2024

The latter issue, which I mentioned, of producing different instantiations is tracked by CWG1286, which is still unresolved, but we should probably implement provisional wording.

There is already an LLVM issue for it: #65843


The original issue, failure to deduce an alias template, I believe clang is correct to reject it.

See https://eel.is/c++draft/temp.deduct#type-8 and more specifically https://eel.is/c++draft/temp.deduct#type-8.2

A template type argument T, a template template argument TT, or a template non-type argument i can be deduced if P and A have one of the following forms:

...
TTopt
...

where

(8.2) TTopt represents either a class template or a template template parameter,

An alias template is neither a class template nor a template template parameter.

And see also this note: https://eel.is/c++draft/temp.alias#note-1

Note 1: An alias template name is never deduced. — end note

@cor3ntin
Copy link
Contributor

cor3ntin commented Apr 30, 2024

@mizvekov I agree with this reading. You might want to improve diagnostics in a separate PR

Edit: Actually, I'm not sure. What we are trying to deduce here is not the alias but its template arguments.
And there is wild divergence. It might be a bug in https://eel.is/c++draft/temp.deduct#type-8 @zygoloid @erichkeane

Edit2: not that much divergence https://godbolt.org/z/jc77frbMz
But this looks like CWG2037/CWG1286/etc

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"
Projects
None yet
Development

No branches or pull requests

7 participants