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

Reply via email to