/* When forming equivalence classes for TYPE_CANONICAL in C23, we treat
structs with the same tag as equivalent, but only when they are targets
of pointers inside other structs. */
- if (data->equiv && data->pointedto)
+ if (data->equiv && data->pointedto && NULL_TREE != c_type_tag (t1))
return true;
/* Different types without tag are incompatible except as an anonymous
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-std=c23 -O2" } */
+
+typedef struct {
+ int *arg;
+ int flags;
+} optStruct;
+
+typedef struct {
+ int *specified;
+ int flags;
+} optEntry;
+
+typedef struct {
+ int short_allowed;
+ optStruct *opt_table;
+} optStruct2;
+
+typedef struct {
+ int short_allowed;
+ optEntry *opt_table;
+} optStruct3;
+
+[[gnu::noipa]]
+void f(int, int, optStruct3 a)
+{
+ a.opt_table[0].flags = 1;
+}
+
+[[gnu::noipa]]
+int alias_bug (void)
+{
+ static optEntry option_def[50];
+ static optStruct3 opt;
+ option_def[0].flags = 0;
+ opt.opt_table = option_def;
+ f (0, 0, opt);
+ return opt.opt_table[0].flags;
+}
+
+int main()
+{
+ if (1 != alias_bug())
+ __builtin_abort();
+}
+
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+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;
+ if (fmpz_bpoly_swap_(B, Q) != &Q_coeffs)
+ __builtin_abort();
+ B->coeffs = &B_coeffs;
+ Q->coeffs = &Q_coeffs;
+ if (fmpz_bpoly_swap_2(B, Q) != &Q_coeffs)
+ __builtin_abort();
+ return 0;
+}
+