https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123356
Bug ID: 123356
Summary: -fstrict-aliasing miscompile struct swap when there is
another identical struct (from flint code base)
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: user202729 at protonmail dot com
Target Milestone: ---
Consider the following code
```
typedef struct
{
long coeffs;
}
fmpz_poly_struct;
typedef struct
{
} n_poly_struct;
typedef struct
{
n_poly_struct * coeffs;
long alloc;
long length;
} n_bpoly_struct;
typedef struct
{
fmpz_poly_struct * coeffs;
long alloc;
long length;
} fmpz_bpoly_struct;
typedef fmpz_bpoly_struct fmpz_bpoly_t[];
__attribute__((noinline))
fmpz_poly_struct * fmpz_bpoly_swap_(fmpz_bpoly_t B, fmpz_bpoly_t Q)
{
fmpz_bpoly_struct t = *B;
*B = *Q;
*Q = t;
return B->coeffs;
}
__attribute__((noinline,optimize("no-strict-aliasing")))
fmpz_poly_struct * fmpz_bpoly_swap_2(fmpz_bpoly_t B, fmpz_bpoly_t Q)
{
fmpz_bpoly_struct t = *B;
*B = *Q;
*Q = t;
return B->coeffs;
}
int main(){
fmpz_poly_struct B_coeffs = {0}, Q_coeffs = {0};
fmpz_bpoly_t B = {0};
fmpz_bpoly_t Q = {0};
B->coeffs = &B_coeffs;
Q->coeffs = &Q_coeffs;
__builtin_printf("%d\n", (int)(fmpz_bpoly_swap_(B, Q) == &Q_coeffs));
B->coeffs = &B_coeffs;
Q->coeffs = &Q_coeffs;
__builtin_printf("%d\n", (int)(fmpz_bpoly_swap_2(B, Q) == &Q_coeffs));
}
```
compile with `gcc -O2 a.c`, then run `./a.out`
Because we first swap B and Q, then return B->coeffs, we would expect both
printf to print 1.
In reality, the first printf print 0, the second printf print 1.
GCC version: 15.1.0, but still happens in trunk. This starts happening at 15.1,
and does not happen at 14.3.
Target: x86-64
Compiler Explorer demo: https://godbolt.org/z/3T6rxbfcq