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

    <tr>
        <th>Summary</th>
        <td>
            std::is_trivially_copyable gives wrong value if constraint on copy assignment operator is not satisfied with clang16/trunk
        </td>
    </tr>

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

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

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

<pre>
    Code as below or on [godbolt](https://godbolt.org/). clang 16/trunk believes `S<int>` is not a trivially_copyable class. clang 15, gcc trunk and MSVC believe otherwise.

```
#include <type_traits>

template<typename T>
struct S {
    T m_t;
    S(S const&) = default;
    S(S&&) = default;
    S& operator=(S const&) requires (!std::is_integral<T>::value) = default;
    ~S() = default;
};

// next five assertions pass for all compilers
static_assert(std::is_trivially_destructible<S<int>>::value);
static_assert(std::is_trivially_copy_constructible<S<int>>::value);
static_assert(std::is_trivially_move_constructible<S<int>>::value);
static_assert(!std::is_copy_assignable<S<int>>::value);
static_assert(!std::is_move_assignable<S<int>>::value);

// compiles with gcc trunk, MSVC and clang 15, fails with clang 16/trunk
static_assert(std::is_trivially_copyable<S<int>>::value);
```
According to the standard:


> A [trivially copyable class](https://timsong-cpp.github.io/cppwp/n4868/class#def:class,trivially_copyable) is a class:
> [(1.1)](https://timsong-cpp.github.io/cppwp/n4868/class#prop-1.1) that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([[special]](https://timsong-cpp.github.io/cppwp/n4868/class#special), [[class.copy.ctor]](https://timsong-cpp.github.io/cppwp/n4868/class#copy.ctor), [[class.copy.assign]](https://timsong-cpp.github.io/cppwp/n4868/class#copy.assign)),
> [(1.2)](https://timsong-cpp.github.io/cppwp/n4868/class#prop-1.2) where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
> [(1.3)](https://timsong-cpp.github.io/cppwp/n4868/class#prop-1.3) that has a trivial, non-deleted destructor ([[class.dtor]](https://timsong-cpp.github.io/cppwp/n4868/class#dtor))[.](https://timsong-cpp.github.io/cppwp/n4868/class#prop-1.sentence-1)


> An [eligible special member function](https://timsong-cpp.github.io/cppwp/n4868/class#def:special_member_function,eligible) is a special member function for which:
> [(6.1)](https://timsong-cpp.github.io/cppwp/n4868/class#special-6.1) the function is not deleted,
> [(6.2)](https://timsong-cpp.github.io/cppwp/n4868/class#special-6.2) the associated constraints ([[temp.constr]](https://timsong-cpp.github.io/cppwp/n4868/temp.constr)), if any, are satisfied, and
> [(6.3)](https://timsong-cpp.github.io/cppwp/n4868/class#special-6.3) no special member function of the same kind is more constrained ([[temp.constr.order]](https://timsong-cpp.github.io/cppwp/n4868/temp.constr.order))[.](https://timsong-cpp.github.io/cppwp/n4868/class#special-6.sentence-1)

S<int> has trivial copy/move constructor and trivial destructor. Its copy assignment operator is not eligible because its constraint is not satisfied. Its move assignment operator is not eligible because it's not declared. Is this a clang bug?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WE9zo7gT_TTypcsUFjE2Bx8SZ1z1O_xOmdqrS4gGtCMkVhLx5rKffUsCDPHYMzu1bFXKiaF5_e_1UxNmragU4oFsX8j2dcU6V2tzuDBV1UzFdJXr4uNw1AUCs5Cj1BfQBrQCsn2pdJFr6cj2ldB97VxrSfJM6InQ03Ar0qYKF7IIuGSqgk1K6MmZTn3zaALf0QJJ4zeSHIVyJPlC0hiEBaUdMHBGvAsm5ceZ6_aD5RI9jLVXtC2hR6g4hx6SqQL-__bbccQG7Wo0F2ExIvEriZ-HzzQefvqvNBGKy65AIMnRfbR4doYJZ304s8ccNq1kDgcjxRqEr1cb60zHHbwB2b30VwAAvkJzdiSZXXkjdP8GXCvrCE0JzYAkr1BgyTp5xzLY_MwsBd2iYU4bkrx-h2_wj04YX2i6J3RjXeH7lDwLexbKYWWYJMkxZBKuvzPZ4Y88_vUWkO4bkN3r9PdQX08JUPing1K8eypZNE5oZaFl1kKpDTApgeumFRKNHSvKnODn3prQ_TzwiRkF9pUXufSdmTHpNp9rWP8M2FPuHOr4n8A3-h0Xgb9paQi7n2u2GGgI9pdBP7V_aK6Fi3D1NLN-gMPI-tmdT3XJhByMb6XjV7v4KyF_loZnzrUphKrAaXA1gnVMFcwET_Mc-8_kCzx7Zby6h8-6dU8qnWisVtWat21UCVd3eSQ0oSfetpeW0JN62qd7_z0A0KTAkiTPw7fjnURp5gWUDR6TWWxe5Ol-E218xguE0hrdrns4cDVzUDMLzIFEZh1ohYBSVCKkr9sPuLJdG99hT6rba8GuJ1qDyk26Ro_-4AmP3LkdpM0fYS-2RS6Y9OktkOGIRjMfQO-hP4F8oFGIehlPE94DX33WS3obEL0_7_J7ntBleeLh4FKjQUDG62XJ4eXjITuEHVeJwfT7XJNlc00-z8TcvdJqXaBEhwWMh9ecwX3Pi-WoVYysysj2JVowSYvKoeK4DoJyXw7Dpnjt9DBP0GCTo4GyU9zvAcvp4uDg3Ds4Xx3Q4xjDVR8fxBK2kUsteH1HO9PFtHPwvk5H-cQpgmH_HUhyZzTTxUZzCoOOYTBrNRfM07OfPyaUsxM__Roc9Xf-JUHnSKMKgSiBqY8wpwbBMidsKUIV7g1uutjgTpUIs6v0Q4Losl8F_P7_TajC96vRBqdyYXG3XJE2BS5YtAFv0dGeyvBwuqc9KojbIG1BnQk93Qp3UObRZtK7CP7n7ENFH0fgKhw5ctZZBBEeGlk5ml1Z0qP-6Bx4gErobhw6LpkJSBZcPW5SqoK8q0hyWhWHpMiSjK3wsEn3aUZ3aRyv6kOcsaTcloztMl6WMc8znj1t0l1Z7nme424lDjSmSZxu0s3TNtum0SZhrNyk-5jHu3SPOXmKsWFCRlK-N_7VeSWs7fCQJsmWriTLUdrwok6pwguEm4RS_95uDv6Zdd5VljzFUlhnJxQnnMTDj9djqIR_Fb8YrSoIW7EfxFmltfpps65dmG3t09K-6ow83PyXoOcj1w2hJx_u8GvdGv07ckfoKSRpCT2FIvwdAAD__yPfTyo">