Any comments about this?  

The fix would need to be backported to 15 and 16.

Martin

Am Montag, dem 11.05.2026 um 18:20 +0200 schrieb Martin Uecker:
> So, annoyingly, I got this wrong.
> 
> Bootstrapped and regression tested on x86_64.
> 
> Best,
> Martin
> 
> 
>     c23: fix TBAA error for function returning structure [PR125252]
>     
>     To fix PR122572 we globbed pointers to structure or union types nested
>     within other structure or union types to a void pointer when computing
>     the TYPE_CANONICAL.  But when doing this for function return types this
>     then leads to wrong aliasing decisions, because for some reason function
>     derivation behaves differently than pointer and array derivation.  Instead
>     of globbing to void, replace the nested structure or union type with an
>     incomplete type instead.
>     
>             PR c/124252
>     
>     gcc/c/ChangeLog:
>     
>             * c-typeck.cc (ptr_to_tagged_member): Return type of member.
>             (c_type_canonical): Use incomplete type.
>     
>     gcc/testsuite/ChangeLog:
>     
>             * gcc.dg/pr125252.c
> 
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 6195d179543..3ffeed73d8c 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -579,8 +579,9 @@ c_reconstruct_complex_type (tree type, tree bottom)
>  
>  /* Helper function for c_canonical_type.  Check whether FIELD
>     contains a pointer to a structure or union with tag,
> -   possibly nested in other type derivations.  */
> -static bool
> +   possibly nested in other type derivations, and return the
> +   type of this nested structure or union.  */
> +static tree
>  ptr_to_tagged_member (tree field)
>  {
>    gcc_assert (FIELD_DECL == TREE_CODE (field));
> @@ -598,17 +599,17 @@ ptr_to_tagged_member (tree field)
>    if (ptr_seen
>        && RECORD_OR_UNION_TYPE_P (type)
>        && NULL_TREE != c_type_tag (type))
> -    return true;
> +    return type;
>  
> -  return false;
> +  return NULL_TREE;
>  }
>  
>  /* For a record or union type, make necessary adaptations so that the
>     type can be used as TYPE_CANONICAL.
>  
>     If the TYPE contains a pointer (possibly nested in other type
> -   derivations) to a structure or union as a member, create a copy
> -   and change such pointers to void pointers.  Otherwise, the middle-end
> +   derivations) to a structure or union as a member, create a copy and
> +   change the nested type to an incomplete type.  Otherwise, the middle-end
>     gets confused when recording component aliases in the case where we
>     have formed equivalency classes that include types for which these
>     member pointers end up pointing to other structure or unions types
> @@ -635,9 +636,15 @@ c_type_canonical (tree type)
>    for (tree x = TYPE_FIELDS (type); x; x = DECL_CHAIN (x))
>      {
>        tree f = copy_node (x);
> -      if (ptr_to_tagged_member (x))
> -     TREE_TYPE (f) = c_reconstruct_complex_type (TREE_TYPE (x),
> -                                                 ptr_type_node);
> +      if (tree m = ptr_to_tagged_member (x))
> +     {
> +       tree new_node = make_node (TREE_CODE (m));
> +       TYPE_NAME (new_node) = TYPE_NAME (m);
> +       SET_TYPE_STRUCTURAL_EQUALITY (new_node);
> +       new_node = qualify_type (new_node, m);
> +       TREE_TYPE (f) = c_reconstruct_complex_type (TREE_TYPE (x),
> +                                                   new_node);
> +     }
>        *fields = f;
>        fields = &DECL_CHAIN (f);
>      }
> diff --git a/gcc/testsuite/gcc.dg/pr125252.c b/gcc/testsuite/gcc.dg/pr125252.c
> new file mode 100644
> index 00000000000..4e27fa15978
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr125252.c
> @@ -0,0 +1,36 @@
> +/* { dg-do run } */
> +/* { dg-options "-std=gnu23 -O2" } */
> +
> +
> +int k;
> +struct S {};
> +
> +#define T struct S
> +
> +T *get_sender () {
> +  k = 1;
> +  return (void *)0;
> +}
> +
> +T *get_cc () { }
> +
> +void test () {
> +        struct {
> +                T *(*get_header) (void);
> +        } reply_to_map[] = {
> +                { get_sender },
> +                { get_cc },
> +        };
> +
> +        for (int i = 0; i < 2; i++) {
> +                asm ("" ::"r"(reply_to_map[i].get_header ()));
> +        }
> +}
> +
> +int main() {
> +        test ();
> +
> +        if (k != 1)
> +            __builtin_abort();
> +}
> +

Reply via email to