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

Reply via email to