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

    <tr>
        <th>Summary</th>
        <td>
            Clang considers non-satisfied constrained operator templates when rewriting operator<=>
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Given the following example <https://godbolt.org/z/WxG73Mhx7>

```c++
// Concept to detect types which look like timespec without requiring the type.
template<typename T>
concept TimeSpecType = requires(T t) {
 t.tv_sec;
                           t.tv_nsec;
 };

class Time {
public:
    constexpr Time(long long s, unsigned int n) : m_seconds(s), m_nanoseconds(n) {}

    constexpr bool operator==(Time const& other) const = default;
    constexpr int operator<=>(Time const& other) const
    {
        if (int cmp = (m_seconds > other.m_seconds ? 1 : m_seconds < other.m_seconds ? -1 : 0); cmp != 0)
            return cmp;
        if (int cmp = (m_nanoseconds > other.m_nanoseconds ? 1 : m_nanoseconds < other.m_nanoseconds ? -1 : 0); cmp != 0)
            return cmp;
        return 0;
 }
private:
    long long m_seconds { 0 };
    unsigned int m_nanoseconds { 0 };
};

#if 1
template <TimeSpecType T>
bool operator>(T const& a, T const& b)
{
    return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec > b.tv_nsec);
}
#endif

int main()
{
    static_assert(Time(1, 0) > Time(0, 100), "");
 static_assert(Time(1, 0) < Time(1, 100), "");
    static_assert(Time(1, 0) >= Time(0, 100), "");
    static_assert(Time(1, 0) <= Time(1, 100), "");
    static_assert(Time(1, 0) == Time(1, 0), "");
 static_assert(Time(1, 0) != Time(1, 100), "");
}
```

If the free function template for operator> on TimeSpecType's is commented out, clang complains that it can't use the operator> it instantiates from it for `operator><int>`. This is clearly invalid, as neither Time nor int satisfy the concept constraint of that template.

If the template is removed by changing #if 1 to #if 0, all the static asserts in main() pass.

If we include `<compare>` and change `operator<=>` to return `std::strong_ordering` instead of `int`, then clang accepts the code with the free function template in place.

GCC trunk accepts the code as-is, and passes the static asserts.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVl9vq7gT_TTOy6iRYxJIHvLQkubqp5_2aSvtY-XAELzX2Kxt-mc__WoMCdD03q20N0JJGIYzZ87M2Jbeq7NB3LPNA9scFrILtXX7-8P_pQ_oFidbvu-_qRc0EGqEymptX5U5A77JptUILMnrEFrPknsmjkwcz7Y8WR2W1p2ZOP7NxPGPt29Z8lv9lrHkkfED4_fDd8r7q2Diga7eGlEgt6bANkCwUGLAIkB4b9HDa62KGrS130Gr7whBNehbLOBVhdp2ARz-1SlHFIkwvbTsgQM2rZYBWZKT1cgG4elKqRjiPakGf2-xeHpvKbnDgIeeie0TBCZ2wLKBKoRleHn2WLDkYvnxJ_qamTPLDtebgYWW3kcOY5S2O2lVkL7XEIU1PuBb66IrE1ttzRnil2cih87EqpagTAATOSf30BBVa0pKxTOxI8_m2UhjR7u5JJgdprzmQU_WarAtOhmsY8mBLrGNrKMTEynYUKMjsGiJSpZYyU6HmVgjKFEdMfMI-_gvsCPOWJPhoypgYkugRdPG8ExsrwoASx57rOXUdoTVXClq70_97npHTjImD30MsaIw0XTTDA5D5wz53fTKD5hO6jJjO7ePjOf2_If-v5D58IjPO7pvWqde4qxNGmhs0omW2QPw2SCQ56x_P6Rw88LtFDGRqApW87EnUWbDPc7-h36OXTe2nKQ5mdyfrjLNmm4QQw5LQqzZ6XqT5SzLqbCT5zQ3ExeRxmiXZWIEiItGrNaY8CVPNKWqprlHxaQyTGw_5-mDDKp4lt6jC8N8MbFdUZa8XyoeL8sKJ-OK82GxYELEa6TyFbQcpsafon2RHun2ZYZfw8wnmL-K5-Ej5n_SsZ_Rr1Ice-SyyU6b5H9Vv5s7RKg6UwRlDVwHpbJuOg1gzWxXZCLzoDwUtmnQBCzBdoFYFFqaM5lbLZXxEGoZQAUopGEiC9B5jGGn2CqAMj5IE5QM6KFytiEjcWApnw5lkisT6E_Kl_BUq56ERun0OyjzIrUqiYb0YFDR6tdvpMb2m4uXQfnqPVK47PZxqJ2Me0_VE77IsPxEsKtEyoPDxr5gCad3KGppznTiGBYeOrT0f2N7Sq3j232Noa-xB2Umgwqt9P5jyFcEZQrdlUhasCQnbaXDXgSQpuxD41yqy96ZciIyrEss5T6UtB4n9z44a87P1pVIByVypCKgLEkFlnISOo3cQ41mKKwsSDI_6FdiPHH9rI-UgVbLYq7ktzyH4Drz_RZP-jsVjy-UGOmB_hPdlotyn5S7ZCcXuF-lmUjXgidiUe9Xp7Qq5RbX2UYm6ywV2-1mvUsqLE8pzzZ8ofaCi4SvuODpOluJJV9nWbkr16tVVa0wrdiaYyOVXmr90tAJdqG873C_2WXbZKHlCbWPJ2UhDL5CfEiDtzks3J7euTt1Z8_WXCsf_IgSVNC4z4f5MF6V6DwYa-76plRYjq1IAzXU8qolnXvRgMNXpwJ12k21F53T-w8ncRXq7rQsbMPEkbgMP3ets39iEZg4xgw8E8eY4T8BAAD__3Xakyg">