Am Montag, dem 02.12.2024 um 22:33 +0000 schrieb Qing Zhao:

....

> > > 
> > > diff --git a/gcc/testsuite/gcc.dg/pr114014.c 
> > > b/gcc/testsuite/gcc.dg/pr114014.c
> > > new file mode 100644
> > > index 00000000000..ab783f4f85d
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/pr114014.c
> > > @@ -0,0 +1,14 @@
> > > +/* PR c/114014
> > > + * { dg-do compile }
> > > + * { dg-options "-std=c23 -g" } */
> > > +
> > > +struct r {
> > > +  int a;
> > > +  char b[];
> > > +};
> > > +struct r {
> > > +  int a;
> > > +  char b[0];
> > > +}; /* { dg-error "redefinition" } */
> > > +
> > > +
> > > 
> > > Is the above testing case claiming that b[] and b[0] are compatible from 
> > > a language semantic point of view?
> > 
> > It would test that we do not crash with checking.
> > 
> > Semantically, in c23 if you redeclare a type in the same scope then
> > it must not only be compatible but is also not allowed to differ.
> > So a redeclaration in the same scope has stricter requirements than
> > compatibility (this also true for typedefs for example).
> 
> So, here does the “compatibility” mean “compatibility from a language 
> semantic point of view” or TBAA-compability? 

When we talk about what is allowed to be used and what warnings/errors
appear in the test, it is about language semantics.   What made the
compiler crash was related to the TBAA semantics.

> > 
> > Whether we allow
> > 
> > struct r {
> >  int a;
> >  char b[];
> > };
> > 
> > struct r {
> >  int a;
> >  char b[0];
> > };
> > 
> > depends on us because the [0] is an extension.
> 
> [0] is an extension for representing FAM ONLY when -fstrict-flex-array<3, when
> -fstrict-flex-array=3 specified, [0] is NOT considered as an extension for 
> FAM anymore. 
> For [1], only when -fstrict-flex-array<2 spedified, it’s considered as an 
> extension for FAM.
> 
> So, I still think that we should consider -fstrict-flex-array and its impact 
> on the GCC extensions [0] and [1]. 

I do not understand what you mean by "consider
-fstrict-flex-array" 

Independent from this option, the types are always different
types, e.g. sizeof(x->b) would still not be allowed for the
first type because x->b is incomplete but allowed for the
second, and return 1 if it were declared with char b[1].  


Martin

> 
> Qing
> >  I would make it
> > compatible but not allow redefinition as the types are different.
> 
> 
> > 
> > 
> > Martin
> > 
> > 
> > > 
> > > thanks.
> > > 
> > > Qing
> > > > even when we do not treat the later as FAM (i.e. still forbid
> > > > out-of-bounds accesses).
> > > > 
> > > > E.g. see Richard's comment: 
> > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114713#c2
> > > > 
> > > > 
> > > > Martin
> > > > 
> > > > > Thanks.
> > > > > 
> > > > > Qing
> > > > > > 
> > > > > > Martin
> > > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > thanks.
> > > > > > > 
> > > > > > > Qing
> > > > > > > > On Nov 23, 2024, at 14:45, Martin Uecker <uec...@tugraz.at> 
> > > > > > > > wrote:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > This patch tries fixes the errors we have because of
> > > > > > > > flexible array members.  I am bit unsure about the exception
> > > > > > > > for the mode. 
> > > > > > > > 
> > > > > > > > Bootstrapped and regression tested on x86_64.
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > Fix type compatibility for types with flexible array member 
> > > > > > > > [PR113688,PR114014,PR117724]
> > > > > > > > 
> > > > > > > > verify_type checks the compatibility of TYPE_CANONICAL using
> > > > > > > > gimple_canonical_types_compatible_p.   But it is stricter than 
> > > > > > > > what the
> > > > > > > > C standard requires and therefor inconsistent with how 
> > > > > > > > TYPE_CANONICAL is set
> > > > > > > > in the C FE.  Here, the logic is changed to ignore array size 
> > > > > > > > when one of the
> > > > > > > > types is a flexible array member.  To not get errors because of 
> > > > > > > > inconsistent
> > > > > > > > number of members, zero-sized arrays are not ignored anymore 
> > > > > > > > when checking
> > > > > > > > fields of a struct (which is stricter than what was done 
> > > > > > > > before).
> > > > > > > > Finally, a exception is added that allows the TYPE_MODE of a 
> > > > > > > > type with
> > > > > > > > flexible array member to differ from another compatible type.
> > > > > > > > 
> > > > > > > >         PR c/113688
> > > > > > > >         PR c/114014
> > > > > > > >         PR c/117724
> > > > > > > > 
> > > > > > > > gcc/ChangeLog:
> > > > > > > >         * tree.cc (gimple_canonical_types_compatible_p): Revise
> > > > > > > >         logic for types with FAM.
> > > > > > > >         (verify_type): Add exception for mode for types with 
> > > > > > > > FAM.
> > > > > > > > 
> > > > > > > > gcc/testsuite/ChangeLog:
> > > > > > > >         * gcc.dg/pr113688.c: New test.
> > > > > > > >         * gcc.dg/pr114014.c: New test.
> > > > > > > >         * gcc.dg/pr117724.c: New test.
> > > > > > > > 
> > > > > > > > diff --git a/gcc/testsuite/gcc.dg/pr113688.c 
> > > > > > > > b/gcc/testsuite/gcc.dg/pr113688.c
> > > > > > > > new file mode 100644
> > > > > > > > index 00000000000..8dee8c86f1b
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/gcc/testsuite/gcc.dg/pr113688.c
> > > > > > > > @@ -0,0 +1,8 @@
> > > > > > > > +/* { dg-do compile } */
> > > > > > > > +/* { dg-options "-g" } */
> > > > > > > > +
> > > > > > > > +struct S{int x,y[1];}*a;
> > > > > > > > +int main(void){
> > > > > > > > + struct S{int x,y[];};
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > diff --git a/gcc/testsuite/gcc.dg/pr114014.c 
> > > > > > > > b/gcc/testsuite/gcc.dg/pr114014.c
> > > > > > > > new file mode 100644
> > > > > > > > index 00000000000..ab783f4f85d
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/gcc/testsuite/gcc.dg/pr114014.c
> > > > > > > > @@ -0,0 +1,14 @@
> > > > > > > > +/* PR c/114014
> > > > > > > > + * { dg-do compile }
> > > > > > > > + * { dg-options "-std=c23 -g" } */
> > > > > > > > +
> > > > > > > > +struct r {
> > > > > > > > +  int a;
> > > > > > > > +  char b[];
> > > > > > > > +};
> > > > > > > > +struct r {
> > > > > > > > +  int a;
> > > > > > > > +  char b[0];
> > > > > > > > +}; /* { dg-error "redefinition" } */
> > > > > > > > +
> > > > > > > > +
> > > > > > > > diff --git a/gcc/testsuite/gcc.dg/pr117724.c 
> > > > > > > > b/gcc/testsuite/gcc.dg/pr117724.c
> > > > > > > > new file mode 100644
> > > > > > > > index 00000000000..d631daeb644
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/gcc/testsuite/gcc.dg/pr117724.c
> > > > > > > > @@ -0,0 +1,16 @@
> > > > > > > > +/* { dg-do compile } */
> > > > > > > > +/* { dg-options "-g" } */
> > > > > > > > +
> > > > > > > > +struct {
> > > > > > > > +  unsigned long len;
> > > > > > > > +  unsigned long size;
> > > > > > > > +  char data[];
> > > > > > > > +}; /* { dg-warning "unnamed struct" } */
> > > > > > > > +struct {
> > > > > > > > +  struct {
> > > > > > > > +    unsigned long len;
> > > > > > > > +    unsigned long size;
> > > > > > > > +    char data[6];
> > > > > > > > +  };
> > > > > > > > +}; /* { dg-warning "unnamed struct" } */
> > > > > > > > +
> > > > > > > > diff --git a/gcc/tree.cc b/gcc/tree.cc
> > > > > > > > index 1da06c7d4e9..dbf6b180496 100644
> > > > > > > > --- a/gcc/tree.cc
> > > > > > > > +++ b/gcc/tree.cc
> > > > > > > > @@ -13900,8 +13900,11 @@ gimple_canonical_types_compatible_p 
> > > > > > > > (const_tree t1, const_tree t2,
> > > > > > > >    || TREE_CODE (t1) == NULLPTR_TYPE)
> > > > > > > >  return true;
> > > > > > > > 
> > > > > > > > -  /* Can't be the same type if they have different mode.  */
> > > > > > > > -  if (TYPE_MODE (t1) != TYPE_MODE (t2))
> > > > > > > > +  /* Can't be compatible types if they have different mode.  
> > > > > > > > We allow
> > > > > > > > +     mismatching modes for types with flexible array member.  
> > > > > > > > */
> > > > > > > > +  if (!flexible_array_type_p (t1)
> > > > > > > > +      && !flexible_array_type_p (t2)
> > > > > > > > +      && (TYPE_MODE (t1) != TYPE_MODE (t2)))
> > > > > > > >  return false;
> > > > > > > > 
> > > > > > > > /* Non-aggregate types can be handled cheaply.  */
> > > > > > > > @@ -13952,7 +13955,7 @@ gimple_canonical_types_compatible_p 
> > > > > > > > (const_tree t1, const_tree t2,
> > > > > > > >  {
> > > > > > > >  case ARRAY_TYPE:
> > > > > > > >    /* Array types are the same if the element types are the 
> > > > > > > > same and
> > > > > > > > - the number of elements are the same.  */
> > > > > > > > + minimum and maximum index are the same.  */
> > > > > > > >    if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), 
> > > > > > > > TREE_TYPE (t2),
> > > > > > > > trust_type_canonical)
> > > > > > > > > > TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
> > > > > > > > @@ -14046,23 +14049,35 @@ gimple_canonical_types_compatible_p 
> > > > > > > > (const_tree t1, const_tree t2,
> > > > > > > >  f1 || f2;
> > > > > > > >  f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
> > > > > > > > {
> > > > > > > > -    /* Skip non-fields and zero-sized fields.  */
> > > > > > > > -    while (f1 && (TREE_CODE (f1) != FIELD_DECL
> > > > > > > > -  || (DECL_SIZE (f1)
> > > > > > > > -      && integer_zerop (DECL_SIZE (f1)))))
> > > > > > > > +    /* Skip non-fields.  */
> > > > > > > > +    while (f1 && (TREE_CODE (f1) != FIELD_DECL))
> > > > > > > >   f1 = TREE_CHAIN (f1);
> > > > > > > > -    while (f2 && (TREE_CODE (f2) != FIELD_DECL
> > > > > > > > -  || (DECL_SIZE (f2)
> > > > > > > > -      && integer_zerop (DECL_SIZE (f2)))))
> > > > > > > > +    while (f2 && (TREE_CODE (f2) != FIELD_DECL))
> > > > > > > >   f2 = TREE_CHAIN (f2);
> > > > > > > > if (!f1 || !f2)
> > > > > > > >   break;
> > > > > > > > +
> > > > > > > > +    tree t1 = TREE_TYPE (f1);
> > > > > > > > +    tree t2 = TREE_TYPE (f2);
> > > > > > > > +
> > > > > > > > +    /* Special case for flexible array members.  */
> > > > > > > > +    if (TREE_CHAIN (f1) == NULL_TREE
> > > > > > > > + && TREE_CHAIN (f2) == NULL_TREE
> > > > > > > > + && TREE_CODE (t1) == ARRAY_TYPE
> > > > > > > > + && TREE_CODE (t2) == ARRAY_TYPE
> > > > > > > > + && (!DECL_NOT_FLEXARRAY (f1)
> > > > > > > > +    || !DECL_NOT_FLEXARRAY (f2))
> > > > > > > > + && TYPE_REVERSE_STORAGE_ORDER (t1) == 
> > > > > > > > TYPE_REVERSE_STORAGE_ORDER (t2)
> > > > > > > > + && TYPE_NONALIASED_COMPONENT (t1) == 
> > > > > > > > TYPE_NONALIASED_COMPONENT (t2)
> > > > > > > > + && gimple_canonical_types_compatible_p
> > > > > > > > + (TREE_TYPE (t1), TREE_TYPE (t2),
> > > > > > > > + trust_type_canonical))
> > > > > > > > +      ;
> > > > > > > > /* The fields must have the same name, offset and type.  */
> > > > > > > > -    if (DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P 
> > > > > > > > (f2)
> > > > > > > > +    else if (DECL_NONADDRESSABLE_P (f1) != 
> > > > > > > > DECL_NONADDRESSABLE_P (f2)
> > > > > > > > > > !gimple_compare_field_offset (f1, f2)
> > > > > > > > > > !gimple_canonical_types_compatible_p
> > > > > > > > -      (TREE_TYPE (f1), TREE_TYPE (f2),
> > > > > > > > -       trust_type_canonical))
> > > > > > > > +      (t1, t2, trust_type_canonical))
> > > > > > > >   return false;
> > > > > > > > }
> > > > > > > > 
> > > > > > > > @@ -14206,6 +14221,9 @@ verify_type (const_tree t)
> > > > > > > >  }
> > > > > > > > 
> > > > > > > > if (COMPLETE_TYPE_P (t) && TYPE_CANONICAL (t)
> > > > > > > > +      /* We allow a mismatch for flexible array members.  */
> > > > > > > > +      && !flexible_array_type_p (t)
> > > > > > > > +      && !flexible_array_type_p (TYPE_CANONICAL (t))
> > > > > > > >    && TYPE_MODE (t) != TYPE_MODE (TYPE_CANONICAL (t)))
> > > > > > > >  {
> > > > > > > >    error ("%<TYPE_MODE%> of %<TYPE_CANONICAL%> is not 
> > > > > > > > compatible");
> > > 
> > > 
> > 
> 

Reply via email to