> On Dec 16, 2022, at 4:17 AM, Richard Biener <rguent...@suse.de> wrote: > > On Thu, 15 Dec 2022, Qing Zhao wrote: > >> >> >>> On Dec 15, 2022, at 2:47 AM, Richard Biener <rguent...@suse.de> wrote: >>> >>> On Wed, 14 Dec 2022, Qing Zhao wrote: >>> >>>> Hi, Richard, >>>> >>>> I guess that we now agreed on the following: >>>> >>>> “ the information that we ran into a trailing array but didn't consider >>>> it a flex array because of -fstrict-flex-arrays is always a useful >>>> information” >>>> >>>> The only thing we didn’t decide is: >>>> >>>> A. Amend such new information to -Warray-bounds when >>>> -fstrict-flex-arrays=N (N>0) specified. >>>> >>>> OR >>>> >>>> B. Issue such new information with a new warning option >>>> -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. >>>> >>>> My current patch implemented B. >>> >>> Plus it implements it to specify a different flex-array variant for >>> the extra diagnostic. >> Could you clarify a little bit on this? (Don’t quite understand…) >>> >>>> If you think A is better, I will change the patch as A. >>> >>> I would tend to A since, as I said, it's useful information that >>> shouldn't be hidden and not adding an option removes odd combination >>> possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. >> >> With current implementation, the above combination will ONLY report the >> misuse of trailing array as flex-array. No out-of-bounds warnings >> issued. >> >>> In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 >>> hardly useful. >> >> The above combination will NOT happen, because there is NO level argument >> for -Wstrict-flex-arrays. >> >> The only combination will be: -fstrict-flex-arrays=N -Wstrict-flex-arrays >> >> When N > 0, -Wstrict-flex-arrays will report any misuse of trailing arrays >> as flexible array per the value of N. >>> >>> But I'm interested in other opinions. >> >> Adding a separate -Wstrict-flex-arrays will provide users a choice to ONLY >> look at the mis-use of trailing arrays as flex-arrays. Without this new >> option, such information will be buried into tons of out-of-bounds messges. >> >> I think this is the major benefit to have one separate new warning >> -Wstrict-flex-arrays. >> >> Do we need to provide the users this choice? > > Ah, OK - I can see the value of auditing code this way before > enabling -fstrict-flex-arrays. Yes, I think the major benefit of this option is to help users to identify all the places where the trailing arrays are misused as flex-arrays at different level of -fstrict-flex-arrays=N, then update their source code accordingly. And finally can enable -fstrict-flex-arrays by default. > >> + 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"); > > "is not present”. Okay. > > The patch is OK with that change. Thanks! Will commit the patch after the change. > > Thanks and sorry for the slow process ...
Thank you for your patience and questions. The discussion is very helpful since I was not 100% sure whether this new warning is necessary or not in the beginning, but now after this discussion I feel confident that it’s a necessary option to be added. Qing > > Richard. > >> Thanks. >> >> Qing >>> >>> Thanks, >>> Richard. >>> >>>> Let me know your opinion. >>>> >>>> thanks. >>>> >>>> Qing >>>> >>>> >>>>> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguent...@suse.de> wrote: >>>>> >>>>> On Tue, 13 Dec 2022, Qing Zhao wrote: >>>>> >>>>>> Richard, >>>>>> >>>>>> Do you have any decision on this one? >>>>>> Do we need this warning option For GCC? >>>>> >>>>> Looking at the testcases it seems that the diagnostic amends >>>>> -Warray-bounds diagnostics for trailing but not flexible arrays? >>>>> Wouldn't it be better to generally diagnose this, so have >>>>> -Warray-bounds, with -fstrict-flex-arrays, for >>>>> >>>>> struct X { int a[1]; }; >>>>> int foo (struct X *p) >>>>> { >>>>> return p->a[1]; >>>>> } >>>>> >>>>> emit >>>>> >>>>> warning: array subscript 1 is above array bounds ... >>>>> note: the trailing array is only a flexible array member with >>>>> -fno-strict-flex-arrays >>>>> >>>>> ? Having -Wstrict-flex-arrays=N and N not agree with the >>>>> -fstrict-flex-arrays level sounds hardly useful to me but the >>>>> information that we ran into a trailing array but didn't consider >>>>> it a flex array because of -fstrict-flex-arrays is always a >>>>> useful information? >>>>> >>>>> But maybe I misunderstood this new diagnostic? >>>>> >>>>> Thanks, >>>>> Richard. >>>>> >>>>> >>>>>> 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 >>>>>>> >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Richard Biener <rguent...@suse.de> >>>>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>>>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>>>> HRB 36809 (AG Nuernberg) >>>> >>>> >>> >>> -- >>> Richard Biener <rguent...@suse.de> >>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>> HRB 36809 (AG Nuernberg) >> >> > > -- > Richard Biener <rguent...@suse.de> > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > HRB 36809 (AG Nuernberg)