Issue |
137885
|
Summary |
A parameter pack appears both empty and non-empty at the same time
|
Labels |
new issue
|
Assignees |
|
Reporter |
HolyBlackCat
|
Found a really concerning bug:
```cpp
template <typename ...P>
struct A {};
struct B
{
consteval B() {} // Making this constexpr makes the assert below pass.
template <typename ...P>
consteval operator A<P...>() const
{
static_assert(sizeof...(P) > 0); // This fails on Clang.
return {};
}
};
template <typename T>
struct type_identity
{
using type = T;
};
template <typename ...P>
void foo(typename type_identity<A<P...>>::type a, P...) {}
int main()
{
foo(B(), 1, 2);
}
```
The `static_assert` fires on Clang, meaning it calls `operator A<>` with no template arguments! But the corresponding function parameter is `A<int, int>`.
Apparently `A<>` gets reinterpreted (!!) into `A<int, int>` at compile-time. E.g. if you add a `int x = sizeof...(P)` data member to it, it'll be `0` despite the type actually being `A<int, int>`.
Here's an example of this being used to `reinterpret_cast` a `float` into an `int`: https://gcc.godbolt.org/z/Txbsj8ofM
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs