<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63371>63371</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
std::equal gives wrong answer on array of arrays
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
AMP999
</td>
</tr>
</table>
<pre>
https://godbolt.org/z/fcchWzz9n
```
int a[2][2] = { {1,1}, {2,2} };
int b[2][2] = { {1,1}, {2,2} };
assert(std::ranges::equal(a, b));
// libc++: wrongly succeeds
// libstdc++, MSVC: correctly fails the assertion
```
libc++'s `std::ranges::equal` is optimized for element types that are `__is_trivially_equality_comparable`.
This optimization should be disabled when the element type is an array type, because arrays are comparable only by array-to-pointer conversion. So direct comparison of array types is non-trivial:
```
assert(memcmp(&a[0], &b[0], sizeof a[0]) == 0);
assert(a[0] != b[0]);
```
Alternatively, this bug could be fixed by changing `QualType::isTriviallyEqualityComparableType` to reject array types. But if we did that, then we would change the triviality of `S` in this example:
```
using A = int[2];
static_assert(__is_trivially_equality_comparable(A));
// True today, but false in the hypothetical: No problem
struct S { A a; bool operator==(const S&) const = default; };
static_assert(__is_trivially_equality_comparable(S));
// Correctly true today, but false in the hypothetical: Yuck!
```
Therefore I think this should be fixed on the libc++ side (to disable the optimization specifically for array types), and not on the Clang side.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVUtv4zYQ_jX0ZRBDomzZOvjgRw30sEULBy16MihyZLFLkypJJav8-mIovzYIgrYLyJBJzeObbz4ORQj6ZBFXbL5h891E9LF1frX-8mtVVZPaqWHVxtgFVqwZ3zO-PzlVOxOnzp8Y378xvm-kbP94e6ssy3YsW7MyuzxpCdpGEGy-4Wy-u7yAFTtgiw39csa3OVvsGN_SkjO-5WxBn3es2FxiAKQw9Q-GESGgj4wvQ1RUULH2wp4wjP_x714YxpeCYtSMV_Q8QgAYKQCja8n4hp5iDa_e2ZMZIPRSIqpwcbjbhqiu5nwLXw6_b8lNOu9RRjNAI7QJEFu8ANTuYyof0vJFAFZmn9RRZqADuC7qs35DBY3zgAbPaCPEoUNKKCIIjxToeNThGL1-0cKY4ZhC6DgcpTt3wovaICuz6Qjjub0HFgQWQut6o6BGUDqQsYLXFm0q6TEnIRIWhPdiSBuJaZSiDzjuhgTonhWcNQPUw_j1Kbqnzmkb0YN09gV90M5O4eBAaSLz4qmDs-Cah0SBUltnny41ElMfqhXgrpIznuW5Y3zJeEkKzkh6pC9e1g_LoN-Qkt22KhImaTN7r6Bb6KsxMJ6T5T3e3eEdtLWJ6K2I-gXNQHkj9aHuTyCv7Df6GypiS7bCnrQ9UWt_64V5Jq6TOHR4vnb5p0uTtze2k1mZQXTg8S_i84HBKWz6CLqBV2qzSvIZYaClvdeEImXG1PkL1ToO1AtWZockSjsCx2_i3Bn8rBF9oBLW6ZhrG6-H_0ZoiCJqebyR-i9EzJfrzw72s-8RolMiEVz3ERphAo6gEdqhc7HFqGVSEPzioPOuNni-xwrR9zLCIQ2mNQhWbKB2zoDr0Ivo_KgNxpfS2RDhwHhJkhlXVKrCRvQmkuN30-t_lXv4rNztbQTF_1b4n738Ssr9qHPPLXpsnEf4mTptv479vs-IUaVujHyfaRC0QmB8Gd11jCSL7ydNh1I3BIPmpvOPAk2VbkFYBdbFa4KtEfaUYk8nalWoqqjEBFd5uVxkRc7zatKu1AKLrMlmmVT5cjkv5ayeS1QVLouqqTM10Sue8SIr80Vezcp5Nc0XjcrqoirrcoZ1Ltksw7PQZmrMy5nuxokOocdVWRSLfGJEjSZcr1i_IqOnuj8FNsuMDjHc3aKOBle3uZ6aCif9gmG8Z0DY8IqeqhtLv465MOm9eX9X69j29VS6M-N7SnF5PXXe0fFmfJ9gBsb3Cek_AQAA__-mPHvg">