[1/1] Replace flag_strict_flex_arrays with DECL_NOT_FLEXARRAY in middle-end

Message ID 20230112230406.2023047-2-qing.zhao@oracle.com
State New
Headers
Series Replace flag_strict_flex_arrays with DECL_NOT_FLEXARRAY in middle-end |

Commit Message

Qing Zhao Jan. 12, 2023, 11:04 p.m. UTC
  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.

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(-)
  

Comments

Richard Biener Jan. 13, 2023, 7 a.m. UTC | #1
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
>
  

Patch

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