<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">