On Mon, 27 Nov 2023, Martin Uecker wrote: > diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h > index a5dd9a37944..ece5b6a5d26 100644 > --- a/gcc/c/c-tree.h > +++ b/gcc/c/c-tree.h > @@ -758,6 +758,7 @@ extern tree require_complete_type (location_t, tree); > extern bool same_translation_unit_p (const_tree, const_tree); > extern int comptypes (tree, tree); > extern bool comptypes_same_p (tree, tree); > +extern int comptypes_equiv_p (tree, tree);
This function should return bool. > @@ -1250,6 +1266,9 @@ comptypes_internal (const_tree type1, const_tree type2, > > if ((d1 == NULL_TREE) != (d2 == NULL_TREE)) > data->different_types_p = true; > + /* Ignore size mismatches. */ > + if (data->equiv) > + return 1; > /* Sizes must match unless one is missing or variable. */ > if (d1 == NULL_TREE || d2 == NULL_TREE || d1 == d2) > return true; > @@ -1467,6 +1486,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree > t2, > if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2))) > return false; > > + if (data->equiv && (C_TYPE_VARIABLE_SIZE (t1) || C_TYPE_VARIABLE_SIZE > (t2))) > + return 0; > + > for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); > s1 && s2; > s1 = DECL_CHAIN (s1), s2 = DECL_CHAIN (s2)) > @@ -1486,6 +1508,15 @@ tagged_types_tu_compatible_p (const_tree t1, > const_tree t2, > && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1), > DECL_FIELD_BIT_OFFSET (s2)) != 1) > return false; > + > + tree st1 = TYPE_SIZE (TREE_TYPE (s1)); > + tree st2 = TYPE_SIZE (TREE_TYPE (s2)); > + > + if (data->equiv > + && st1 && TREE_CODE (st1) == INTEGER_CST > + && st2 && TREE_CODE (st2) == INTEGER_CST > + && !tree_int_cst_equal (st1, st2)) > + return 0; And these functions do return bool, so you should use true and false instead of 1 and 0. > +/* The structs are incompatible so can be assumed not to > + * alias, but this is not exploited. So do not check for > + * this below but check the warning about incompatibility. */ > + > +int test_bar3(struct bar* a, void* b) > +{ > + a->x = 1; > + > + struct bar { int x; int f[1]; }* p = b; > + struct bar* q = a; /* { dg-warning "incompatible" > } */ I expect you'll now need -fpermissive or -Wno-error=incompatible-pointer-types (this is an execution test so you need to stop this being an error, but see below). > + // allow both results here > + int r = test_bar3(&z, &z); > + if ((r != 2) && (r != 1)) > + __builtin_abort(); I don't think you should really be executing this call at all (aliasing not allowed means undefined behavior at runtime); better to put this in a separate compile-only test (which would also avoid the need for -fpermissive or -Wno-error=incompatible-pointer-types because once it's no longer an execution test, having an error is OK). -- Joseph S. Myers jos...@codesourcery.com