Message ID | 20230112230406.2023047-2-qing.zhao@oracle.com |
---|---|
State | New |
Headers | show |
Series | Replace flag_strict_flex_arrays with DECL_NOT_FLEXARRAY in middle-end | expand |
On Thu, 12 Jan 2023, Qing Zhao wrote: > We should not directly check flag_strict_flex_arrays in the middle end. > Instead, check DECL_NOT_FLEXARRAY(array_field_decl) which is set by > C/C++ FEs according to -fstrict-flex-arrays and the corresponding attribute > attached to the array_field. > > As a result, We will lose the LEVEL information of -fstrict-flex-arrays in > the middle end. -Wstrict-flex-arrays will not be able to issue such > information. update the testing cases accordingly. OK. Thanks, Richard. > gcc/ChangeLog: > > * attribs.cc (strict_flex_array_level_of): Move this function to ... > * attribs.h (strict_flex_array_level_of): Remove the declaration. > * gimple-array-bounds.cc (array_bounds_checker::check_array_ref): > replace the referece to strict_flex_array_level_of with > DECL_NOT_FLEXARRAY. > * tree.cc (component_ref_size): Likewise. > > gcc/c/ChangeLog: > > * c-decl.cc (strict_flex_array_level_of): ... here. > > gcc/testsuite/ChangeLog: > > * gcc.dg/Warray-bounds-flex-arrays-1.c: Delete the level information > from the message issued by -Wstrict-flex-arrays. > * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. > * gcc.dg/Wstrict-flex-arrays-2.c: Likewise. > * gcc.dg/Wstrict-flex-arrays-3.c: Likewise. > * gcc.dg/Wstrict-flex-arrays.c: Likewise. > --- > gcc/attribs.cc | 30 ------------ > gcc/attribs.h | 2 - > gcc/c/c-decl.cc | 28 +++++++++++ > gcc/gimple-array-bounds.cc | 46 ++++--------------- > .../gcc.dg/Warray-bounds-flex-arrays-1.c | 2 +- > .../gcc.dg/Warray-bounds-flex-arrays-2.c | 4 +- > .../gcc.dg/Warray-bounds-flex-arrays-3.c | 6 +-- > .../gcc.dg/Warray-bounds-flex-arrays-4.c | 2 +- > .../gcc.dg/Warray-bounds-flex-arrays-5.c | 4 +- > .../gcc.dg/Warray-bounds-flex-arrays-6.c | 6 +-- > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 8 ++-- > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 8 ++-- > gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 8 ++-- > gcc/tree.cc | 37 +++------------ > 14 files changed, 68 insertions(+), 123 deletions(-) > > diff --git a/gcc/attribs.cc b/gcc/attribs.cc > index 49cb299a3c1..7db730cf831 100644 > --- a/gcc/attribs.cc > +++ b/gcc/attribs.cc > @@ -2456,36 +2456,6 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs) > } > } > > -/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the > - values of attribute strict_flex_array and the flag_strict_flex_arrays. */ > -unsigned int > -strict_flex_array_level_of (tree array_field) > -{ > - gcc_assert (TREE_CODE (array_field) == FIELD_DECL); > - unsigned int strict_flex_array_level = flag_strict_flex_arrays; > - > - tree attr_strict_flex_array > - = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field)); > - /* If there is a strict_flex_array attribute attached to the field, > - override the flag_strict_flex_arrays. */ > - if (attr_strict_flex_array) > - { > - /* Get the value of the level first from the attribute. */ > - unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; > - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); > - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); > - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); > - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); > - gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); > - attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); > - > - /* The attribute has higher priority than flag_struct_flex_array. */ > - strict_flex_array_level = attr_strict_flex_array_level; > - } > - return strict_flex_array_level; > -} > - > - > /* Return the access specification for a function parameter PARM > or null if the current function has no such specification. */ > > diff --git a/gcc/attribs.h b/gcc/attribs.h > index e7540f71d6a..140e70b64e0 100644 > --- a/gcc/attribs.h > +++ b/gcc/attribs.h > @@ -398,6 +398,4 @@ extern void init_attr_rdwr_indices (rdwr_map *, tree); > extern attr_access *get_parm_access (rdwr_map &, tree, > tree = current_function_decl); > > -extern unsigned int strict_flex_array_level_of (tree); > - > #endif // GCC_ATTRIBS_H > diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc > index d76ffb3380d..38647c100c1 100644 > --- a/gcc/c/c-decl.cc > +++ b/gcc/c/c-decl.cc > @@ -9047,6 +9047,34 @@ finish_incomplete_vars (tree incomplete_vars, bool toplevel) > } > } > > +/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the > + values of attribute strict_flex_array and the flag_strict_flex_arrays. */ > +static unsigned int > +strict_flex_array_level_of (tree array_field) > +{ > + gcc_assert (TREE_CODE (array_field) == FIELD_DECL); > + unsigned int strict_flex_array_level = flag_strict_flex_arrays; > + > + tree attr_strict_flex_array > + = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field)); > + /* If there is a strict_flex_array attribute attached to the field, > + override the flag_strict_flex_arrays. */ > + if (attr_strict_flex_array) > + { > + /* Get the value of the level first from the attribute. */ > + unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; > + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); > + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); > + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); > + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); > + gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); > + attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); > + > + /* The attribute has higher priority than flag_struct_flex_array. */ > + strict_flex_array_level = attr_strict_flex_array_level; > + } > + return strict_flex_array_level; > +} > > /* Determine whether the FIELD_DECL X is a flexible array member according to > the following info: > diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc > index 116200a317f..66fd46e9b6c 100644 > --- a/gcc/gimple-array-bounds.cc > +++ b/gcc/gimple-array-bounds.cc > @@ -350,18 +350,14 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > /* Set to the type of the special array member for a COMPONENT_REF. */ > special_array_member sam{ }; > - > + tree afield_decl = NULL_TREE; > tree arg = TREE_OPERAND (ref, 0); > - const bool compref = TREE_CODE (arg) == COMPONENT_REF; > - unsigned int strict_flex_array_level = flag_strict_flex_arrays; > > - if (compref) > + if (TREE_CODE (arg) == COMPONENT_REF) > { > /* Try to determine special array member type for this COMPONENT_REF. */ > sam = component_ref_sam_type (arg); > - /* Get the level of strict_flex_array for this array field. */ > - tree afield_decl = TREE_OPERAND (arg, 1); > - strict_flex_array_level = strict_flex_array_level_of (afield_decl); > + afield_decl = TREE_OPERAND (arg, 1); > } > > get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); > @@ -412,39 +408,15 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > /* issue warnings for -Wstrict-flex-arrays according to the level of > flag_strict_flex_arrays. */ > - if (out_of_bound && warn_strict_flex_arrays) > - switch (strict_flex_array_level) > - { > - case 3: > - /* Issue additional warnings for trailing arrays [0]. */ > - if (sam == special_array_member::trail_0) > + if ((out_of_bound && warn_strict_flex_arrays) > + && (((sam == special_array_member::trail_0) > + || (sam == special_array_member::trail_1) > + || (sam == special_array_member::trail_n)) > + && DECL_NOT_FLEXARRAY (afield_decl))) > warned = warning_at (location, OPT_Wstrict_flex_arrays, > "trailing array %qT should not be used as " > - "a flexible array member for level 3", > + "a flexible array member", > artype); > - /* FALLTHROUGH. */ > - case 2: > - /* Issue additional warnings for trailing arrays [1]. */ > - if (sam == special_array_member::trail_1) > - warned = warning_at (location, OPT_Wstrict_flex_arrays, > - "trailing array %qT should not be used as " > - "a flexible array member for level 2 and " > - "above", artype); > - /* FALLTHROUGH. */ > - case 1: > - /* Issue warnings for trailing arrays [n]. */ > - if (sam == special_array_member::trail_n) > - warned = warning_at (location, OPT_Wstrict_flex_arrays, > - "trailing array %qT should not be used as " > - "a flexible array member for level 1 and " > - "above", artype); > - break; > - case 0: > - /* Do nothing. */ > - break; > - default: > - gcc_unreachable (); > - } > > /* Avoid more warnings when checking more significant subscripts > of the same expression. */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > index 65c9fec43af..fd2aacf6452 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > @@ -32,7 +32,7 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > index 2b5a895c598..55b7535424b 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > @@ -32,9 +32,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > index 25b903f2615..abdf8f15c78 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > @@ -32,11 +32,11 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > index 5fc500a19ca..82b38ff1ad1 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > @@ -32,7 +32,7 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > index 30bb4ca8832..dca02288be7 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > @@ -32,9 +32,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > index e847a44516e..fc9f73b4535 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > @@ -32,11 +32,11 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > - /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > index 2e241f96208..befc604f19b 100644 > --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_3 *trailing_0, > struct trailing_array_4 *trailing_flex) > { > - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > - trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > - trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member" } */ > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > index 97eb65ba0a9..cc37a092c3e 100644 > --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_3 *trailing_0, > struct trailing_array_4 *trailing_flex) > { > - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > - trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > - trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ > - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member" } */ > + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > index 110fdc72778..735b23a1dc6 100644 > --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_3 *trailing_0, > struct trailing_array_4 *trailing_flex) > { > - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > - trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > - trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ > + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member" } */ > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ > > } > diff --git a/gcc/tree.cc b/gcc/tree.cc > index 78b64ee98b3..7473912a065 100644 > --- a/gcc/tree.cc > +++ b/gcc/tree.cc > @@ -13074,38 +13074,15 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) > || *sam == special_array_member::trail_n) > return memsize; > > - /* flag_strict_flex_arrays will control how to treat > - the trailing arrays as flexiable array members. */ > - > tree afield_decl = TREE_OPERAND (ref, 1); > - unsigned int strict_flex_array_level > - = strict_flex_array_level_of (afield_decl); > - > - switch (strict_flex_array_level) > - { > - case 3: > - /* Treaing 0-length trailing arrays as normal array. */ > - if (*sam == special_array_member::trail_0) > - return size_zero_node; > - /* FALLTHROUGH. */ > - case 2: > - /* Treating 1-element trailing arrays as normal array. */ > - if (*sam == special_array_member::trail_1) > - return memsize; > - /* FALLTHROUGH. */ > - case 1: > - /* Treating 2-or-more elements trailing arrays as normal > - array. */ > - if (*sam == special_array_member::trail_n) > - return memsize; > - /* FALLTHROUGH. */ > - case 0: > - break; > - default: > - gcc_unreachable (); > - } > + gcc_assert (TREE_CODE (afield_decl) == FIELD_DECL); > + /* if the trailing array is a not a flexible array member, treat it as > + a normal array. */ > + if (DECL_NOT_FLEXARRAY (afield_decl) > + && *sam != special_array_member::int_0) > + return memsize; > > - if (*sam == special_array_member::int_0) > + if (*sam == special_array_member::int_0) > memsize = NULL_TREE; > > /* For a reference to a flexible array member of a union >
diff --git a/gcc/attribs.cc b/gcc/attribs.cc index 49cb299a3c1..7db730cf831 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -2456,36 +2456,6 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs) } } -/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the - values of attribute strict_flex_array and the flag_strict_flex_arrays. */ -unsigned int -strict_flex_array_level_of (tree array_field) -{ - gcc_assert (TREE_CODE (array_field) == FIELD_DECL); - unsigned int strict_flex_array_level = flag_strict_flex_arrays; - - tree attr_strict_flex_array - = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field)); - /* If there is a strict_flex_array attribute attached to the field, - override the flag_strict_flex_arrays. */ - if (attr_strict_flex_array) - { - /* Get the value of the level first from the attribute. */ - unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); - gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); - attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); - - /* The attribute has higher priority than flag_struct_flex_array. */ - strict_flex_array_level = attr_strict_flex_array_level; - } - return strict_flex_array_level; -} - - /* Return the access specification for a function parameter PARM or null if the current function has no such specification. */ diff --git a/gcc/attribs.h b/gcc/attribs.h index e7540f71d6a..140e70b64e0 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -398,6 +398,4 @@ extern void init_attr_rdwr_indices (rdwr_map *, tree); extern attr_access *get_parm_access (rdwr_map &, tree, tree = current_function_decl); -extern unsigned int strict_flex_array_level_of (tree); - #endif // GCC_ATTRIBS_H diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index d76ffb3380d..38647c100c1 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9047,6 +9047,34 @@ finish_incomplete_vars (tree incomplete_vars, bool toplevel) } } +/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the + values of attribute strict_flex_array and the flag_strict_flex_arrays. */ +static unsigned int +strict_flex_array_level_of (tree array_field) +{ + gcc_assert (TREE_CODE (array_field) == FIELD_DECL); + unsigned int strict_flex_array_level = flag_strict_flex_arrays; + + tree attr_strict_flex_array + = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field)); + /* If there is a strict_flex_array attribute attached to the field, + override the flag_strict_flex_arrays. */ + if (attr_strict_flex_array) + { + /* Get the value of the level first from the attribute. */ + unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); + attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); + + /* The attribute has higher priority than flag_struct_flex_array. */ + strict_flex_array_level = attr_strict_flex_array_level; + } + return strict_flex_array_level; +} /* Determine whether the FIELD_DECL X is a flexible array member according to the following info: diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 116200a317f..66fd46e9b6c 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -350,18 +350,14 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, /* Set to the type of the special array member for a COMPONENT_REF. */ special_array_member sam{ }; - + tree afield_decl = NULL_TREE; tree arg = TREE_OPERAND (ref, 0); - const bool compref = TREE_CODE (arg) == COMPONENT_REF; - unsigned int strict_flex_array_level = flag_strict_flex_arrays; - if (compref) + if (TREE_CODE (arg) == COMPONENT_REF) { /* Try to determine special array member type for this COMPONENT_REF. */ sam = component_ref_sam_type (arg); - /* Get the level of strict_flex_array for this array field. */ - tree afield_decl = TREE_OPERAND (arg, 1); - strict_flex_array_level = strict_flex_array_level_of (afield_decl); + afield_decl = TREE_OPERAND (arg, 1); } get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); @@ -412,39 +408,15 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, /* issue warnings for -Wstrict-flex-arrays according to the level of flag_strict_flex_arrays. */ - if (out_of_bound && warn_strict_flex_arrays) - switch (strict_flex_array_level) - { - case 3: - /* Issue additional warnings for trailing arrays [0]. */ - if (sam == special_array_member::trail_0) + if ((out_of_bound && warn_strict_flex_arrays) + && (((sam == special_array_member::trail_0) + || (sam == special_array_member::trail_1) + || (sam == special_array_member::trail_n)) + && DECL_NOT_FLEXARRAY (afield_decl))) warned = warning_at (location, OPT_Wstrict_flex_arrays, "trailing array %qT should not be used as " - "a flexible array member for level 3", + "a flexible array member", artype); - /* FALLTHROUGH. */ - case 2: - /* Issue additional warnings for trailing arrays [1]. */ - if (sam == special_array_member::trail_1) - warned = warning_at (location, OPT_Wstrict_flex_arrays, - "trailing array %qT should not be used as " - "a flexible array member for level 2 and " - "above", artype); - /* FALLTHROUGH. */ - case 1: - /* Issue warnings for trailing arrays [n]. */ - if (sam == special_array_member::trail_n) - warned = warning_at (location, OPT_Wstrict_flex_arrays, - "trailing array %qT should not be used as " - "a flexible array member for level 1 and " - "above", artype); - break; - case 0: - /* Do nothing. */ - break; - default: - gcc_unreachable (); - } /* Avoid more warnings when checking more significant subscripts of the same expression. */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c index 65c9fec43af..fd2aacf6452 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c @@ -32,7 +32,7 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c index 2b5a895c598..55b7535424b 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c @@ -32,9 +32,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c index 25b903f2615..abdf8f15c78 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c @@ -32,11 +32,11 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c index 5fc500a19ca..82b38ff1ad1 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c @@ -32,7 +32,7 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c index 30bb4ca8832..dca02288be7 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c @@ -32,9 +32,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c index e847a44516e..fc9f73b4535 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c @@ -32,11 +32,11 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ - /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ + /*{ dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ - /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ + /* { dg-warning "should not be used as a flexible array member" "" { target *-*-* } .-1 } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ } diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c index 2e241f96208..befc604f19b 100644 --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_3 *trailing_0, struct trailing_array_4 *trailing_flex) { - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ - trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ - trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member" } */ + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ } diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c index 97eb65ba0a9..cc37a092c3e 100644 --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_3 *trailing_0, struct trailing_array_4 *trailing_flex) { - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ - trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ - trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member" } */ + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ } diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c index 110fdc72778..735b23a1dc6 100644 --- a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c @@ -31,9 +31,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_3 *trailing_0, struct trailing_array_4 *trailing_flex) { - normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ - trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ - trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ - trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member" } */ + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member" } */ + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member" } */ } diff --git a/gcc/tree.cc b/gcc/tree.cc index 78b64ee98b3..7473912a065 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -13074,38 +13074,15 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) || *sam == special_array_member::trail_n) return memsize; - /* flag_strict_flex_arrays will control how to treat - the trailing arrays as flexiable array members. */ - tree afield_decl = TREE_OPERAND (ref, 1); - unsigned int strict_flex_array_level - = strict_flex_array_level_of (afield_decl); - - switch (strict_flex_array_level) - { - case 3: - /* Treaing 0-length trailing arrays as normal array. */ - if (*sam == special_array_member::trail_0) - return size_zero_node; - /* FALLTHROUGH. */ - case 2: - /* Treating 1-element trailing arrays as normal array. */ - if (*sam == special_array_member::trail_1) - return memsize; - /* FALLTHROUGH. */ - case 1: - /* Treating 2-or-more elements trailing arrays as normal - array. */ - if (*sam == special_array_member::trail_n) - return memsize; - /* FALLTHROUGH. */ - case 0: - break; - default: - gcc_unreachable (); - } + gcc_assert (TREE_CODE (afield_decl) == FIELD_DECL); + /* if the trailing array is a not a flexible array member, treat it as + a normal array. */ + if (DECL_NOT_FLEXARRAY (afield_decl) + && *sam != special_array_member::int_0) + return memsize; - if (*sam == special_array_member::int_0) + if (*sam == special_array_member::int_0) memsize = NULL_TREE; /* For a reference to a flexible array member of a union