Issue |
123498
|
Summary |
clang-trunk fails to compile valid code
|
Labels |
new issue
|
Assignees |
|
Reporter |
beached
|
It looks like a recent change has broken the following code and it is instantiating the else branch of an if constexpr
https://gcc3.godbolt.org/z/YvKjrEKsG
```cpp
#include <cstddef>
#include <functional>
#include <type_traits>
template <typename T>
struct remove_array_ref;
template <typename T, std::size_t N>
struct remove_array_ref<T (&)[N]> {
using type = T[N];
};
template <typename T>
using remove_array_ref_t = typename remove_array_ref<T>::type;
template <typename T, typename Compare = std::equal_to<>,
typename U = std::enable_if_t<std::is_array_v<remove_array_ref_t<T>>,
remove_array_ref_t<T>>>
constexpr bool array_cmp(T && lhs, T &&rhs, Compare const &cmp = Compare{}) {
for (size_t n = 0; n < std::extent_v<U>; ++n) {
if constexpr (std::rank_v<U> == 1) {
if (not cmp(lhs[n], rhs[n])) {
return false;
}
} else {
if (not array_cmp(lhs[n], rhs[n], cmp)) {
return false;
}
}
}
return true;
}
int main() {
{
constexpr int ints1[]{1, 2, 3, 4};
constexpr int ints2[]{1, 2, 3, 4};
static_assert(array_cmp(ints1, ints2));
}
{
constexpr int ints3[2][4]{{1, 2, 3, 4}, {1, 2, 3, 4}};
constexpr int ints4[2][4]{{1, 2, 3, 4}, {1, 2, 3, 4}};
static_assert(array_cmp(ints3, ints4));
}
}
```
```
<source>:25:21: error: no matching function for call to 'array_cmp'
25 | if (not array_cmp(lhs[n], rhs[n], cmp)) {
| ^~~~~~~~~
<source>:37:23: note: in instantiation of function template specialization 'array_cmp<const int (&)[4], std::equal_to<void>, const int[4]>' requested here
37 | static_assert(array_cmp(ints1, ints2));
| ^
<source>:18:16: note: candidate template ignored: substitution failure [with T = const int &, Compare = std::equal_to<void>]: implicit instantiation of undefined template 'remove_array_ref<const int &>'
13 | using remove_array_ref_t = typename remove_array_ref<T>::type;
| ~~~~~
14 |
15 | template <typename T, typename Compare = std::equal_to<>,
16 | typename U = std::enable_if_t<std::is_array_v<remove_array_ref_t<T>>,
17 | remove_array_ref_t<T>>>
18 | constexpr bool array_cmp(T && lhs, T &&rhs, Compare const &cmp = Compare{}) {
| ^
<source>:37:23: error: static assertion _expression_ is not an integral constant _expression_
37 | static_assert(array_cmp(ints1, ints2));
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:42:23: error: static assertion _expression_ is not an integral constant _expression_
42 | static_assert(array_cmp(ints3, ints4));
| ^~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
Compiler returned: 1
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs