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

    <tr>
        <th>Summary</th>
        <td>
            clang generates aligned instructions dereferencing a pointer to a type alias declared with __aligned__(1)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          ben-cohen-xs
      </td>
    </tr>
</table>

<pre>
    *The following bug report assumes that defining a pointer type with the attribute `__aligned__(1)` tells the compiler that it must not assume that the value is aligned and it must generate unaligned instructions.  (For example, it must generate `movups` instead of `movaps`.  The gcc [manual](https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Common-Type-Attributes.html) is a bit vague about this assumption but this StackOverflow [answer](https://stackoverflow.com/questions/47510783/why-does-u) by Peter Cordes is clear that it is correct.)*

The following test case, for x86_64, defines `uint128_u` as a [type alias](https://en.cppreference.com/w/cpp/language/type_alias) of `__uint128_t` with alignment 1.  The `main()` function passes two `void*` pointers that are _not_ aligned to 16 bytes to the `compare()` function, which casts them to `uint128_u*` and dereferences them.

The code generated by `clang` uses aligned instructions which cause the program to fail with a segmentation fault.  This happens whether or not you use optimization, but it doesn't happen if you use a `typedef` instead of `using`.  It also doesn't happen if you use `gcc`.

**Test case**
* To reproduce, compile the files below on x86_64:
```
clang++ -c -o compare.o compare.cpp -Wall
clang++ -c -o test.o test.cpp -Wall
clang++ -o test test.o compare.o -Wall
```

* To run:
```
./test
```

* Expected behaviour: execution succeeds
* Observed behaviour: segmentation fault with a misaligned memory access in compare() at `movaps` for -O0 or `movdqa` for -O3


**compare.h**
```
#ifndef COMPARE_H
#define COMPARE_H

extern bool compare(const void* v1, const void* v2);

#endif
```

**compare.cpp**
```
#include "compare.h"

#define USE_USING 1

#if USE_USING
using uint128_u = __attribute__((__aligned__(1), may_alias)) __uint128_t;
#else
typedef __attribute__((__aligned__(1), may_alias)) __uint128_t uint128_u;
#endif

bool compare(const void* v1, const void* v2)
{
    return *static_cast<const uint128_u*>(v1)
        == *static_cast<const uint128_u*>(v2);
}
```

**test.cpp**
```
// test.cpp: Test to demonstrate that clang does not generate unaligned
// instructions for a type alias declared with `using` and
// __aligned__(1).
//
// Compile on x86_64 with
//    clang++ -c -o compare.o compare.cpp -Wall
//    clang++ -c -o test.o test.cpp -Wall
//    clang++ -o test test.o compare.o -Wall
// Run with
// ./test
//
// Expected behaviour: execution succeeds
// Observed behaviour: segmentation fault with a misaligned memory access
// in compare() at `movaps` for -O0 or `movdqa` for -O3
//
// The problem does not happen if you use g++ or change USE_USING to 0 in
// compare.cpp.

#include <cstdlib>
#include <cstdint>
#include <iostream>

#include "compare.h"

int main()
{
 __attribute__((__aligned__(16))) char some_bytes[40] = {};

    if (((uintptr_t)(&some_bytes) % 16) != 0)
    {
        abort();
 }

    // v1 and v2 intentionally have alignment at non-16-byte addresses
    void *v1 = &(some_bytes[8]);
    void *v2 = &(some_bytes[24]);

    bool result = compare(v1, v2);
    std::cout << "Result: " << result << std::endl;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWM2S4jgSfhrVJQPCyGDMgQNFNbtz2O2J7p7YIyHkNNauLHkkmSr26SdStgFDV_XMRBMVUJaUqfz58kvJwnt1NIhrtnhmi5cn0YbKuvUBzUTaCs3kzT8dbHFeM775ViGUVmv7qswRDu0RHDbWBRDetzV6CJUIUGCpDC0Q0FhlAjoI5wbhVYUKQoUgQnDq0AYEliX7vdBkQLHfM57PGF-xLIGAWvu4WNq6UZp0kG4VoG59AGOHTbtxWnkSukVQHnqFIExxETiiQScCQmuGaWV8cK0Myho_BWA831kH-CbqRiPj20dZliW1PbWNJxNJHEUBtuzHRRyfAlCYjlICWzzXwrRCs8UL43kVQuNZumF8x_juKOX0aNqpdUfGd9ZoZbCw0ndTk1k6nU2T7oHx3dbWtTWTb-cGJ5shfH5ahVozvopOw0EFOIljiyAOtqWY0DAFqSEf4TCMfQ1C_u_zCV2p7StZKYx_Rfc9Kz0ttf3SqbQ147vfW_QxaIzv5svFLFnmKeO71-o8KSz6SUsWHc7wK1Lqt9YV6MlCqVFc00gD1jmUYUo55xuWvLCk_x4DLaAPIIWPSSmtg7c822dzeopYQ08ZaJUJM57vW0qOoICwxXMEntBK-O95h2Yqm8ZhiQ6NxN6_V8Z3smkY32lhjq04IuM7UrTvFPFVn_P9ftgz0J4R3xFcNZoAsx4JBA6hDON5j-2yNRF00AjvqWheLS06WVVQGLJkKJu-noRD2Bsb9hdgBwuzDA7nQNI2gp9lCVWKcPi4EQXqtVKyoiCGWFY1yY2C1u1MJVPgJSLd2ul9aqQt8FIVBeWatqdokY6WnPpekV2MaD1Goxtnj05EW0qhdB9B8HikCIoYpFK0OsRQKg-VaBqMijBU6MC6yARn29KuYJugavV_MThNiFcBCJWG8WXo5UGVFxFBplNyCywfq7r1Kvo0BfglgNDefqiMZQmVa5aMIkah5ZtvVxBvrmjnG_hmiUWdLVoZAd4TXgxQqTR6OCDVqTUD7tNBOkv6v_jYJYA_M_4MEwkTCz0iptf_ZNPA5D9C6_dEqNam_c9Hi7slw_LrRjfr78wbe9ya99yYUrWhDz9Q8umtQRnRh5U4Kds6lm4A31C2ETe-lRKx8FeJzweP7nQv8Qi2AYa18gOKa6ytO4OQEr0HZWBUayDCqAVEjpp8Tgie3Xjxu7iOpyNXbiAyRLEaQeQuADxVpSmwhO3nf_26-fJp_8_LREeGDxPxG98COgMHa_WN8dIaH6BnHjjNOvyNxjiRSfo8tjZFU6jy4wzdOBTZ9EOXjNRtgcA4vwkCv9u09--3r5_2v3395d__gNndAlVeJ7vBWMBwYTlg6Qvs95cDSDxzMJ5_5xDCt1CL84XyKc23fH-JCE9Re-weeh75KTtcjR7tdRP3-P03E9ppWPaKAQAchtYZYHzjqRjknnoFS7ed9KhPpJ8Yz0-zix7oPyx9ofj-eRVjbC1ffgiogZY-RBN19guBUYlH6g0WCqzJkniUi501Mlpk9NhGHs-II5WjVkalLOB6vIACpRYOi449bnoH9dSRnkcoTG_nR2u3fTO4kH9UP1oCAH-D-T8S_qAHvCP2Z7pBJ_mlNY8u3FH-Yxj-KtlHoZ_F93cg-Cnc_-jit-48dNBYXxH5eMQYQm4dyEqY4y0dBgt0gBmpvUn_9J4tB9JNt9KHQqsDleU7s8qEd2aV9cGhqK_Tf4HVlQlwczq-o6Uf82jWESclQlbCgbc17uPBmC2e5wlbvETKJ5XLl7s2RihWJXR6Gc-JoJrg9iEqzBnPbrTxFTC-gLghMD4jrcmIAUdsSh9xsC70jg07w5XlroJdpk6zePo-caDDvyF8Cq3PUIkT3lwrBF1-zWSWTcgwEEXhkK4RV33E9ETCp1nnO88Yz0eByeNl6MaqWyn-nhSf34ldhWMXcuipmkj6WiJdCxozPUn4UNABMN1IuqqydMvSLQHlS1RChco4H8YvmuPTRRRNoT9oH0_FOi1W6Uo84XqW5avFapklq6dqjcmMF_kc-WqV8VlaCJnPk3xZCp4dVnnKn9SaJzxNlrPljM-TJJ9mclkWy_kyKfMEy1XJ5gnWQump1qearvBPyvsW11m6SrInLQ6o_fBCxa1p0eTQHj2bJ1r54K9iQQWN664PDe3nncvT9Vp2927FftSIHpvNU-v0-u5dhApVe-ivv2Rb_zNpnP0vysD4LvpHN_7o4h8BAAD__5l-h-Q">