Richard, 

Do you have any decision on this one? 
Do we need this warning option For GCC? 

thanks.

Qing

> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.z...@oracle.com> wrote:
> 
> '-Wstrict-flex-arrays'
>     Warn about inproper usages of flexible array members according to
>     the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to
>     the trailing array field of a structure if it's available,
>     otherwise according to the LEVEL of the option
>     '-fstrict-flex-arrays=LEVEL'.
> 
>     This option is effective only when LEVEL is bigger than 0.
>     Otherwise, it will be ignored with a warning.
> 
>     when LEVEL=1, warnings will be issued for a trailing array
>     reference of a structure that have 2 or more elements if the
>     trailing array is referenced as a flexible array member.
> 
>     when LEVEL=2, in addition to LEVEL=1, additional warnings will be
>     issued for a trailing one-element array reference of a structure if
>     the array is referenced as a flexible array member.
> 
>     when LEVEL=3, in addition to LEVEL=2, additional warnings will be
>     issued for a trailing zero-length array reference of a structure if
>     the array is referenced as a flexible array member.
> 
> gcc/ChangeLog:
> 
>       * doc/invoke.texi: Document -Wstrict-flex-arrays option.
>       * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more
>       arguments.
>       (array_bounds_checker::check_array_ref): Issue warnings for
>       -Wstrict-flex-arrays.
>       * opts.cc (finish_options): Issue warning for unsupported combination
>       of -Wstrict_flex_arrays and -fstrict-flex-array.
>       * tree-vrp.cc (execute_ranger_vrp): Enable the pass when
>       warn_strict_flex_array is true.
> 
> gcc/c-family/ChangeLog:
> 
>       * c.opt (Wstrict-flex-arrays): New option.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with
>       -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.
>       * c-c++-common/Wstrict-flex-arrays.c: New test.
>       * gcc.dg/Wstrict-flex-arrays-2.c: New test.
>       * gcc.dg/Wstrict-flex-arrays-3.c: New test.
>       * gcc.dg/Wstrict-flex-arrays.c: New test.
> ---
> gcc/c-family/c.opt                            |   5 +
> gcc/doc/invoke.texi                           |  27 ++++-
> gcc/gimple-array-bounds.cc                    | 103 ++++++++++++++----
> gcc/opts.cc                                   |   8 ++
> .../c-c++-common/Wstrict-flex-arrays.c        |   9 ++
> .../gcc.dg/Warray-bounds-flex-arrays-1.c      |   5 +-
> .../gcc.dg/Warray-bounds-flex-arrays-2.c      |   6 +-
> .../gcc.dg/Warray-bounds-flex-arrays-3.c      |   7 +-
> .../gcc.dg/Warray-bounds-flex-arrays-4.c      |   5 +-
> .../gcc.dg/Warray-bounds-flex-arrays-5.c      |   6 +-
> .../gcc.dg/Warray-bounds-flex-arrays-6.c      |   7 +-
> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c  |  39 +++++++
> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c  |  39 +++++++
> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c    |  39 +++++++
> gcc/tree-vrp.cc                               |   2 +-
> 15 files changed, 273 insertions(+), 34 deletions(-)
> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c
> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c
> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c
> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
> 
> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> index 0d0ad0a6374..33edeefd285 100644
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -976,6 +976,11 @@ Wstringop-truncation
> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) 
> LangEnabledBy(C ObjC C++ LTO ObjC++, Wall)
> Warn about truncation in string manipulation functions like strncat and 
> strncpy.
> 
> +Wstrict-flex-arrays
> +C C++ Var(warn_strict_flex_arrays) Warning
> +Warn about inproper usages of flexible array members
> +according to the level of -fstrict-flex-arrays.
> +
> Wsuggest-attribute=format
> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
> Warn about functions which might be candidates for format attributes.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 726392409b6..4402b0427ef 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}.
> -Wstrict-aliasing=n  -Wstrict-overflow  -Wstrict-overflow=@var{n} @gol
> -Wstring-compare @gol
> -Wno-stringop-overflow -Wno-stringop-overread @gol
> --Wno-stringop-truncation @gol
> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol
> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]}
>  @gol
> -Wswitch  -Wno-switch-bool  -Wswitch-default  -Wswitch-enum @gol
> -Wno-switch-outside-range  -Wno-switch-unreachable  -Wsync-nand @gol
> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that 
> expect
> such arrays GCC issues warnings unless it can prove that the use is
> safe.  @xref{Common Variable Attributes}.
> 
> +@item -Wstrict-flex-arrays
> +@opindex Wstrict-flex-arrays
> +@opindex Wno-strict-flex-arrays
> +Warn about inproper usages of flexible array members
> +according to the @var{level} of the @code{strict_flex_array (@var{level})}
> +attribute attached to the trailing array field of a structure if it's
> +available, otherwise according to the @var{level} of the option
> +@option{-fstrict-flex-arrays=@var{level}}.
> +
> +This option is effective only when @var{level} is bigger than 0.  Otherwise,
> +it will be ignored with a warning.
> +
> +when @var{level}=1, warnings will be issued for a trailing array reference
> +of a structure that have 2 or more elements if the trailing array is 
> referenced
> +as a flexible array member.
> +
> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be
> +issued for a trailing one-element array reference of a structure
> +if the array is referenced as a flexible array member.
> +
> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be
> +issued for a trailing zero-length array reference of a structure
> +if the array is referenced as a flexible array member.
> +
> +
> @item 
> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]}
> @opindex Wsuggest-attribute=
> @opindex Wno-suggest-attribute=
> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
> index db3459af325..825f11331b5 100644
> --- a/gcc/gimple-array-bounds.cc
> +++ b/gcc/gimple-array-bounds.cc
> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl,
> 
> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND
>    and UP_BOUND_P1, check whether the array reference REF is out of bound.
> -   Issue warnings if out of bound, return TRUE if warnings are issued.  */ 
> +   When out of bounds, set OUT_OF_BOUND to true.
> +   Issue warnings if FOR_ARRAY_BOUND is true.
> +   return TRUE if warnings are issued.  */
> +
> 
> static bool
> check_out_of_bounds_and_warn (location_t location, tree ref,
>                             tree low_sub_org, tree low_sub, tree up_sub,
>                             tree up_bound, tree up_bound_p1,
>                             const value_range *vr,
> -                           bool ignore_off_by_one)
> +                           bool ignore_off_by_one, bool for_array_bound,
> +                           bool *out_of_bound)
> {
>   tree low_bound = array_ref_low_bound (ref);
>   tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
> 
>   bool warned = false;
> +  *out_of_bound = false;
> 
>   /* Empty array.  */
>   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
> -    warned = warning_at (location, OPT_Warray_bounds_,
> -                      "array subscript %E is outside array bounds of %qT",
> -                      low_sub_org, artype);
> +    {
> +      *out_of_bound = true;
> +      if (for_array_bound)
> +     warned = warning_at (location, OPT_Warray_bounds_,
> +                          "array subscript %E is outside array"
> +                          " bounds of %qT", low_sub_org, artype);
> +    }
> 
>   if (warned)
>     ; /* Do nothing.  */
> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree 
> ref,
>             : tree_int_cst_le (up_bound, up_sub))
>         && TREE_CODE (low_sub) == INTEGER_CST
>         && tree_int_cst_le (low_sub, low_bound))
> -     warned = warning_at (location, OPT_Warray_bounds_,
> -                          "array subscript [%E, %E] is outside "
> -                          "array bounds of %qT",
> -                          low_sub, up_sub, artype);
> +     {
> +       *out_of_bound = true;
> +       warned = warning_at (location, OPT_Warray_bounds_,
> +                            "array subscript [%E, %E] is outside "
> +                            "array bounds of %qT",
> +                            low_sub, up_sub, artype);
> +     }
>     }
>   else if (up_bound
>          && TREE_CODE (up_sub) == INTEGER_CST
>          && (ignore_off_by_one
>              ? !tree_int_cst_le (up_sub, up_bound_p1)
>              : !tree_int_cst_le (up_sub, up_bound)))
> -    warned = warning_at (location, OPT_Warray_bounds_,
> -                      "array subscript %E is above array bounds of %qT",
> -                      up_sub, artype);
> +    {
> +      *out_of_bound = true;
> +      warned = warning_at (location, OPT_Warray_bounds_,
> +                        "array subscript %E is above array bounds of %qT",
> +                        up_sub, artype);
> +    }
>   else if (TREE_CODE (low_sub) == INTEGER_CST
>          && tree_int_cst_lt (low_sub, low_bound))
> -    warned = warning_at (location, OPT_Warray_bounds_,
> -                      "array subscript %E is below array bounds of %qT",
> -                      low_sub, artype);
> +    {
> +      *out_of_bound = true;
> +      warned = warning_at (location, OPT_Warray_bounds_,
> +                        "array subscript %E is below array bounds of %qT",
> +                        low_sub, artype);
> +    }
>   return warned;
> }
> 
> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t 
> location, tree ref,
> 
>   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)
> -    /* Try to determine special array member type for this COMPONENT_REF.  */
> -    sam = component_ref_sam_type (arg);
> +    {
> +      /* 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);
> +    }
> 
>   get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1);
> 
>   bool warned = false;
> +  bool out_of_bound = false;
> 
>   tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
>   tree low_sub_org = TREE_OPERAND (ref, 1);
> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t 
> location, tree ref,
>   warned = check_out_of_bounds_and_warn (location, ref,
>                                        low_sub_org, low_sub, up_sub,
>                                        up_bound, up_bound_p1, vr,
> -                                      ignore_off_by_one);
> +                                      ignore_off_by_one, warn_array_bounds,
> +                                      &out_of_bound);
> 
> 
>   if (!warned && sam == special_array_member::int_0)
> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t 
> location, tree ref,
>                              "of an interior zero-length array %qT")),
>                        low_sub, artype);
> 
> -  if (warned)
> +  if (warned || out_of_bound)
>     {
> -      if (dump_file && (dump_flags & TDF_DETAILS))
> +      if (warned && dump_file && (dump_flags & TDF_DETAILS))
>       {
>         fprintf (dump_file, "Array bound warning for ");
>         dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
>         fprintf (dump_file, "\n");
>       }
> 
> +      /* 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)
> +           warned = warning_at (location, OPT_Wstrict_flex_arrays,
> +                                "trailing array %qT should not be used as "
> +                                "a flexible array member for level 3",
> +                                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.  */
>       ref = TREE_OPERAND (ref, 0);
>       suppress_warning (ref, OPT_Warray_bounds_);
> +      suppress_warning (ref, OPT_Wstrict_flex_arrays);
> 
>       if (decl)
>       ref = decl;
> diff --git a/gcc/opts.cc b/gcc/opts.cc
> index 73fc97756e4..8db53ad6c77 100644
> --- a/gcc/opts.cc
> +++ b/gcc/opts.cc
> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct 
> gcc_options *opts_set,
>       opts->x_profile_flag = 0;
>     }
> 
> +  if (opts->x_warn_strict_flex_arrays)
> +    if (opts->x_flag_strict_flex_arrays == 0)
> +      {
> +     opts->x_warn_strict_flex_arrays = 0;
> +     warning_at (UNKNOWN_LOCATION, 0,
> +                 "%<-Wstrict-flex-arrays%> is ignored when"
> +                 " %<-fstrict-flex-arrays%> does not present");
> +      }
> 
>   diagnose_options (opts, opts_set, loc);
> }
> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c 
> b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c
> new file mode 100644
> index 00000000000..72b4b7c6406
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c
> @@ -0,0 +1,9 @@
> +/* Test the usage of option -Wstrict-flex-arrays.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */
> +
> +int main(int argc, char *argv[])
> +{
> +    return 0;
> +}
> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" 
> "" { target *-*-* } 0 } */
> 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 d36ba4d86cb..65c9fec43af 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
> /* { dg-do compile} */
> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 
> -Warray-bounds" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,6 +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 } */
>     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 f63206e1948..2b5a895c598 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 
> -Warray-bounds" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,7 +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 } */
>     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 } */
>     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 e3273714e8b..25b903f2615 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 
> -Warray-bounds" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,8 +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 } */
>     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 } */
>     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 } */
>     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 cabaea77dc2..5fc500a19ca 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 
> -Warray-bounds=2" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,6 +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 } */
>     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 8b7db6e4f39..30bb4ca8832 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 
> -Warray-bounds=2" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,7 +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 } */
>     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 } */
>     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 035bf481396..e847a44516e 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
> @@ -1,6 +1,6 @@
> -/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 
> -Warray-bounds=2" } */
> 
> struct trailing_array_1 {
>     int a;
> @@ -32,8 +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 } */
>     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 } */
>     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 } */
>     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
> new file mode 100644
> index 00000000000..2e241f96208
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c
> @@ -0,0 +1,39 @@
> +/* Test -Wstrict-flex-arrays.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */
> +
> +struct trailing_array_1 {
> +    int a;
> +    int b;
> +    int c[4]; 
> +};
> +
> +struct trailing_array_2 {
> +    int a;
> +    int b;
> +    int c[1]; 
> +};
> +
> +struct trailing_array_3 {
> +    int a;
> +    int b;
> +    int c[0];
> +};
> +struct trailing_array_4 {
> +    int a;
> +    int b;
> +    int c[];
> +};
> +
> +void __attribute__((__noinline__)) stuff(
> +    struct trailing_array_1 *normal,
> +    struct trailing_array_2 *trailing_1,
> +    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" } */
> +
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c 
> b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c
> new file mode 100644
> index 00000000000..97eb65ba0a9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c
> @@ -0,0 +1,39 @@
> +/* Test -Wstrict-flex-arrays.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */
> +
> +struct trailing_array_1 {
> +    int a;
> +    int b;
> +    int c[4]; 
> +};
> +
> +struct trailing_array_2 {
> +    int a;
> +    int b;
> +    int c[1]; 
> +};
> +
> +struct trailing_array_3 {
> +    int a;
> +    int b;
> +    int c[0];
> +};
> +struct trailing_array_4 {
> +    int a;
> +    int b;
> +    int c[];
> +};
> +
> +void __attribute__((__noinline__)) stuff(
> +    struct trailing_array_1 *normal,
> +    struct trailing_array_2 *trailing_1,
> +    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" } */
> +
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c 
> b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
> new file mode 100644
> index 00000000000..110fdc72778
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
> @@ -0,0 +1,39 @@
> +/* Test -Wstrict-flex-arrays.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */
> +
> +struct trailing_array_1 {
> +    int a;
> +    int b;
> +    int c[4]; 
> +};
> +
> +struct trailing_array_2 {
> +    int a;
> +    int b;
> +    int c[1]; 
> +};
> +
> +struct trailing_array_3 {
> +    int a;
> +    int b;
> +    int c[0];
> +};
> +struct trailing_array_4 {
> +    int a;
> +    int b;
> +    int c[];
> +};
> +
> +void __attribute__((__noinline__)) stuff(
> +    struct trailing_array_1 *normal,
> +    struct trailing_array_2 *trailing_1,
> +    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" } */
> +
> +}
> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> index 3846dc1d849..e6c6c5a301d 100644
> --- a/gcc/tree-vrp.cc
> +++ b/gcc/tree-vrp.cc
> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool 
> warn_array_bounds_p,
>   if (dump_file && (dump_flags & TDF_DETAILS))
>     ranger->dump (dump_file);
> 
> -  if (warn_array_bounds && warn_array_bounds_p)
> +  if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p)
>     {
>       // Set all edges as executable, except those ranger says aren't.
>       int non_exec_flag = ranger->non_executable_edge_flag;
> -- 
> 2.31.1
> 


Reply via email to