<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/59021>59021</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libc++] std::equal cannot compare between ranges of element with and without volatile qualifier
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          alvinhochun
      </td>
    </tr>
</table>

<pre>
    The following code does not compile with libc++ from LLVM 15.

https://godbolt.org/z/6WaPjT8e4

```c++
int a[3] { 1, 2, 3 };
std::span<int> x(a, 3);
std::span<volatile int> y(a, 3);
std::equal(x.begin(), x.end(), y.begin(), y.end());
```

```
In file included from <source>:1:
In file included from /opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/span:145:
In file included from /opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/array:111:
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/__algorithm/equal.h:28:10: error: no matching function for call to object of type 'std::__equal_to<int>'
    if (!__pred(*__first1, *__first2))
         ^~~~~~
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/__algorithm/equal.h:59:17: note: in instantiation of function template specialization 'std::equal<std::__wrap_iter<int *>, std::__wrap_iter<volatile int *>, std::__equal_to<int> &>' requested here
  return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
                ^
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/__algorithm/equal.h:77:17: note: in instantiation of function template specialization 'std::__equal<std::__equal_to<int>, std::__wrap_iter<int *>, std::__wrap_iter<volatile int *>>' requested here
  return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
                ^
<source>:8:16: note: in instantiation of function template specialization 'std::equal<std::__wrap_iter<int *>, std::__wrap_iter<volatile int *>>' requested here
    (void)std::equal(x.begin(), x.end(), y.begin(), y.end());
               ^
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/__algorithm/comp.h:36:10: note: candidate function not viable: 2nd argument ('volatile int') would lose volatile qualifier
    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
         ^
1 error generated.
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzVVtuO2zYQ_Rr5hVhBoi6WH_TgXcdAgBQo2kX6KFDSSGZAiwpFee18fYfUxZd4N2iRbhGDpngZkjPnzJCTy_KUPu-AVFII-cKbmhSyBFJK6EgjNfb2LRdAXrjeEcHzwqGPWEil5J58-vT5N-JHruNtHG891Dut284J1g7dYqllmUuhXalq7H3Df_wX-_3LcwLh5SIn9oYybj-M8kYT5kSPgRNtiLN8JL5Dnwg1VYD9jROMgp0uzYnBumtZ4wRPuNAJPpCjQxNmpR26elX4IAXTxsRx1entVfC1ZwJFjm4ONW-wZcRQ_OhCU567p9v50-X8eePZ9Lt4DN2PDakGDQvRl1AO6KPunexVAag1KuYb_d4Sp1vZaqxHStUDHFshFSgzJlhTPyCVnuthNzeKb10Xq3ETIzNyQ7cHJGI7wLf2w-idD2ZKsZM52T-b_LPPyDImaqnQ6ffYs5y7OzwN6cODPawIKCWVaTSS7JkudiZ4qr4pNJeIg1SkYEIQLYnMv0ChiayIPrWAeCxnb8oyu3em5ey2OD3YRPDHK2Jdxs-yVsHgPrio4qrTNhrOXTo61rzW_pzog7O8Lu8KWLQygC0HnDSYL2-wdJo1mjOLFQIz46Zh32I8AulaKDgT_NsgcwnaEILo_WcUXxRrM65RewujgcVC-UReEbqM-vvS3xGDYvHAD1E4CZ1GD9-BgglyBbpXDck-__m8udY0-4M1pdyviwK67iNqwLRUlr-7M-aKu-Hxgs535W-5_Pn8jdheM3gnDl4l718z_M_Ym_SkyWXEZZlgc3OKvGl4bF4Yk2WHUfZA7fnje_Ajfq8vd3vtxL9EFL2FMTG32UFyvMhW_9mL-v-EjNnURkwQz0_ExFWBMc5Lw8fMkMmtDpzlwgrQpiRM1f0eLI5o0fIqLcEnga7Ii-xFSYTsgMyzBjtecbRhtj2XUhDZDlfJBE9SSPQWkj2j5jE649EAeDN2MocMY5htTfGQHTHTwIjYWAkEGROv798YO-IPjyKpoTGnQ-nepDMLSP04TqKVt_SSRZkG5SpYsYXmWkCKmd45wTQp37WHGBSnjJQpIDnoF4CGKCQOk1V0fxBgAbS5KkJuG7LXd9Ba9EqkN6kqCve5i9tjR4jD9HlolTTvt3GFrkOnxgYaQP3FLo2LIA_zgJaVF8c-TXxGoyKMqiCheRKG0UKwHERnTEODFjylHqWYt8TeikZe4oYhiymEecl8Fq3ilRN6sGdcuOZgkzQvVGp1yPu6w0nBO92dJ1nX8boBmPZnPdqrUiYOvNnJYtc3C6tyavX9GwiFk5U">