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

    <tr>
        <th>Summary</th>
        <td>
            Is disallowing loading an `_Atomic(...)` type with `__atomic_load` intended?
        </td>
    </tr>

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

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

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

<pre>
    I have the following example snippet, which compiles with GCC, but not with Clang. 
(https://godbolt.org/z/7PbjeTn1x)

```c
#include <stdatomic.h>
int main(int argc, char ** argv) {
  _Atomic int a;
 int value;
  __atomic_load(&a, &value, memory_order_relaxed);
  return 0;
}
```

Clang emits the following error message; `<source>:5:3: error: address argument to atomic operation must be a pointer to a trivially-copyable type ('_Atomic(int) *' invalid)`

This is being emitted from `Sema::BuildAtomicExpr` in `SemaChecking.cpp`;
```cpp
if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) &&
 !AtomTy->isScalarType()) {
    // For GNU atomics, require a trivially-copyable type. This is not part of
    // the GNU atomics specification, but we enforce it for sanity.
 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_trivial_copy)
 << Ptr->getType() << Ptr->getSourceRange();
    return ExprError();
 }
```
`AtomTy` is
```c
AtomicType 0x1258d10c0 '_Atomic(int)'
`-BuiltinType 0x1258417b0 'int'
```

I tried adding a clause to `QualType::isTriviallyCopyableType` and `Type::isScalarType` to look through the `AtomicType` at the underlying `ValueType`, but that resulted in some test failures. (Most are in C++ tests, which I'm less concerned with at the moment since I don't think the `_Atomic` spelling is even a thing in C++). The most prevalent is the failure in `Sema/atomic-ops.c`;
```c
void f(_Atomic(int) *i, const _Atomic(int) *ci,
       _Atomic(int*) *p, _Atomic(float) *f, _Atomic(double) *d,
 _Atomic(long double) *ld,
       int *I, const int *CI,
       int **P, float *D, struct S *s1, struct S *s2) {
  ...
  __atomic_load(i, I, memory_order_relaxed); // expected-error {{must be a pointer to a trivially-copyable type}}
  ...
}
```

Is this discrepancy intentional? I'm afraid I'm not familiar enough with the C atomic types to know what the desired behavior is. `IsC11` is defined as 

```cpp
bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_init &&
 Op <= AtomicExpr::AO__c11_atomic_fetch_min) ||
 IsOpenCL;
 ```

Would it make more sense to include a GNU atomics check instead of looking through the `_Atomic` type? 
```cpp
bool IsGNU = (Op >= AtomicExpr::AO__atomic_load &&
              Op <= AtomicExpr::AO__atomic_nand_fetch)
```

Thanks!
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUV11z47oN_TXMCyYemYpl58EPjrK-45m2u-2m7aOHIiGLNxSpkpQT99d3QEnrj02292Y8sUWCIHB4DkCJEPTBIq7Z4oktnu9EHxvn1xjlmzYK7yqnTusdNOKIEBuE2hnj3rQ9AL6LtjMIwequw8h4CW-Nlg1I13baYIA3HRv4rSxpquojWBeHsdIIe5gBy55ZtmF81cTYBZZvGN8yvj04VTkTZ84fGN_-l_Ht8lv1O77Y-Tvjj-Oi4X-RDR85ucq1laZXCCwvQ1QiulbLWcPyL4OFthFaoS3jK_op_EFSdLIRHhjfML6hsSPjj8CWT8MagP0m-YG0hOXTOD0ehenxPAT7_bDn3jihGF8xXgjagfFiMOUltNg6f9o7r9DvPRrxjooyO3vxGHtvIfsxxJbPNylf4pDwBGx1DLeH5L3z0GII4kBhAq3My-B6L5FQyTcLlm9ylm8GW_ohlPIYAiHRt2gjRAdDVuA69CJqZ6HtQ4QKQUDntI3okxVEr49aGHO6l647icogxFOHkKBYjkAO6CeQCfMlaHsURicQrjN7aXQAHaBCPWYYUUHtXUuZfMdWEG3yzVOvjRqcf3nvPCsy0HYyKRuUr9oeZrLrUv5Pt_TpupEe9RDofBfK-ZwOjfECGJ-T65fTTIeXKb9yTO_l1CHjq9LZiO9jTrRqPMofa-9Z_kWH71IY4cc1lO410QAGCcDWefjtb_8cYQ_EGo__6bXHzzGewYQWCa0TPoKrf_JM_LjwDKFDqWst06lOSn1DQFs7LxF0hNp5CMLqeJqN7p61ODC-Iqj_IewBZweMT3hIukpZlaDIJJ0Nej-JwnV7i6jCfkxhTwn8EDWJluUlfIue0DpgPAP189z3xOG0_bhrfoHjqCCK8Evi9Y3Jp4IqsuG8EoXCx3VmIBoFB9n7nC9Wap7JDD4gOOPLHy7uiaRR24t1D_NlldYl6-UvJL6jU0dF2iQlCJBG9AFJdKzI_t4Lk7BKgH_G0iIDYRXZX9peULLIyJ9x7hVi411_aBJdRkyGjJOXmMZ7q9CbE8XDiuxfVN5Gi4lHsRERPIbekGy1heBahIghQi206T2GGSnury5QMUYyKRl_YvwpWYVzV9kxvmzBUF2Szkr0FtXQTcZoWpdqVdBWIuxAEZuXNKXt65TGdDxFRrw3hkLXAfCIlnTVpOcfITD-SJoi1yFC5_EoDG2hxyo7ZHBRaBjfDkS_d12YyY9rzfB8dFpBzfjqo5KoU09yNkT4aFrS_JnqALdWm9GwIz_nudo4Mfmor6eU6yuD45w6uz9bGGcPcGVm1G0Y1BAZ3-zO4Y8j5e4TU8Y338g6hUYDz_QUou9lhO80EOY_jfCbqjmbzT5rvwnJ3a-b7lQZ8b1DGVHdD02TNlg-_bk2R1VlKiwXcf26e--ITjqA0kF67ISVJ4IHLVVkYVi-Hckvai-0Gh-oxtei1UYLD2iTWJMciJrl1K8pqEAhv1r3Bm_NqBWFQXtUUGEjjtp50KTDIkttb6h8oLDWpDER4OM719Q0K-cMjA0zfyY5f-0g3S2e4aIlp3Kz-brfy_l8OiVtdbzul2lp-QeW1hhls2-p5RAZSvoMLnbha4e2_MtFsf8I9n-73ihqb614JYl7hIB2KKnTLVJctUpJ9wjQNkQUClydKiWVjJtieVFlEinyLfwf7GiXP4TdBbuvcbv6-zWIow8rrBpQPN-qP8LppRH2NTA-v1PrXD3mj-IO1_NiuVjy1WK1umvWef34MJe8KLKHouJFLlePVbHIUGQVX2T1_E6vecbzjGfLLMseH1YztcqXPF_IhwqXebXK2EOGrdBmZsyxpYv_nQ6hx3WRLZb8zogKTUhvKJxbfIM0yTinFxa_pjX3VX8I7CEzOsRw9hJ1NLjeJW2J6U5M4KUeai8Pi69IrukCOtxYk5jI4KqkpItlRKtQsXx713uzvnl70bHpq5l0LeNbCmT8uu-8-x1lZHybwg-Mb1N6_wsAAP__YicVNA">