Make Warray-bounds alias to Warray-bounds= [PR107787]

Message ID 9795E6AA-E646-4134-AABE-23F530F5219E@ispras.ru
State Accepted
Headers
Series Make Warray-bounds alias to Warray-bounds= [PR107787] |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Iskander Shakirzyanov Nov. 23, 2022, 1:29 p.m. UTC
  From 51559e862d191a1f51cc9af11f0d9be5fbc0b43c Mon Sep 17 00:00:00 2001
From: Iskander Shakirzyanov <iskander@ispras.ru>
Date: Wed, 23 Nov 2022 12:26:47 +0000
Subject: [PATCH] Make Warray-bounds alias to Warray-bounds= [PR107787]

	PR driver/107787

gcc/ChangeLog:

	* common.opt (Warray-bounds): Turn into alias to
	-Warray-bounds=1.
	* builtins.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
	* diagnostic-spec.cc: Likewise.
	* gimple-array-bounds.cc: Likewise.
	* gimple-ssa-warn-restrict.cc: Likewise.

gcc/testsuite/ChangeLog:

	* pr107787.c: New test.

gcc/c-family/ChangeLog:

	* c-common.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
---
 gcc/builtins.cc                 |  6 +++---
 gcc/c-family/c-common.cc        |  4 ++--
 gcc/common.opt                  |  2 +-
 gcc/diagnostic-spec.cc          |  1 -
 gcc/gimple-array-bounds.cc      | 38 ++++++++++++++++-----------------
 gcc/gimple-ssa-warn-restrict.cc |  2 +-
 gcc/testsuite/gcc.dg/pr107787.c | 13 +++++++++++
 7 files changed, 39 insertions(+), 27 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr107787.c
  

Comments

Iskander Shakirzyanov Nov. 23, 2022, 2:08 p.m. UTC | #1
Hi!
Sorry for the initially missing description. 
The following patch changes the definition of -Warray-bounds to an Alias to -Warray-bounds=1. This is necessary for the correct use of -Werror=array-bounds=X, for more information see bug report 107787 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107787)
As I understand, this happens because -Warray-bounds and -Warray-bounds= are declared as 2 different options in common.opt, so when diagnostic_classify_diagnostic() (opts-common.cc:1880) is called, DK_ERROR is set for the -Warray-bounds= option, but in diagnostic_report_diagnostic() (diagnostic.cc:1446) through warning_at() passes opt_index of -Warray-bounds, so information about DK_ERROR is lost.


From 51559e862d191a1f51cc9af11f0d9be5fbc0b43c Mon Sep 17 00:00:00 2001
From: Iskander Shakirzyanov <iskander@ispras.ru>
Date: Wed, 23 Nov 2022 12:26:47 +0000
Subject: [PATCH] Make Warray-bounds alias to Warray-bounds= [PR107787]

	PR driver/107787

gcc/ChangeLog:

	* common.opt (Warray-bounds): Turn into alias to
	-Warray-bounds=1.
	* builtins.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
	* diagnostic-spec.cc: Likewise.
	* gimple-array-bounds.cc: Likewise.
	* gimple-ssa-warn-restrict.cc: Likewise.

gcc/testsuite/ChangeLog:

	* pr107787.c: New test.

gcc/c-family/ChangeLog:

	* c-common.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
---
 gcc/builtins.cc                 |  6 +++---
 gcc/c-family/c-common.cc        |  4 ++--
 gcc/common.opt                  |  2 +-
 gcc/diagnostic-spec.cc          |  1 -
 gcc/gimple-array-bounds.cc      | 38 ++++++++++++++++-----------------
 gcc/gimple-ssa-warn-restrict.cc |  2 +-
 gcc/testsuite/gcc.dg/pr107787.c | 13 +++++++++++
 7 files changed, 39 insertions(+), 27 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr107787.c

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4dc1ca672b2..02c4fefa86f 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
     {
       /* Suppress multiple warnings for propagated constant strings.  */
       if (only_value != 2
-	  && !warning_suppressed_p (arg, OPT_Warray_bounds)
-	  && warning_at (loc, OPT_Warray_bounds,
+	  && !warning_suppressed_p (arg, OPT_Warray_bounds_)
+	  && warning_at (loc, OPT_Warray_bounds_,
 			 "offset %qwi outside bounds of constant string",
 			 eltoff))
 	{
 	  if (decl)
 	    inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
-	  suppress_warning (arg, OPT_Warray_bounds);
+	  suppress_warning (arg, OPT_Warray_bounds_);
 	}
       return NULL_TREE;
     }
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 6f1f21bc4c1..b0da6886ccf 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
 		     definition thereof.  */
 		  if (TREE_CODE (v) == ARRAY_REF
 		      || TREE_CODE (v) == COMPONENT_REF)
-		    warning (OPT_Warray_bounds,
+		    warning (OPT_Warray_bounds_,
 			     "index %E denotes an offset "
 			     "greater than size of %qT",
 			     t, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -8534,7 +8534,7 @@ convert_vector_to_array_for_subscript (location_t loc,
       if (TREE_CODE (index) == INTEGER_CST)
         if (!tree_fits_uhwi_p (index)
 	    || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
-          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+          warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
 
       /* We are building an ARRAY_REF so mark the vector as addressable
          to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
diff --git a/gcc/common.opt b/gcc/common.opt
index 26e9d1cc4e7..e475d6e56eb 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -539,7 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
 Warn if a loop with constant number of iterations triggers undefined behavior.
 
 Warray-bounds
-Common Var(warn_array_bounds) Warning
+Common Alias(Warray-bounds=, 1, 0) Warning
 Warn if an array is accessed out of bounds.
 
 Warray-bounds=
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index aece89619e7..7a03fc493e6 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
       break;
 
       /* Access warning group.  */
-    case OPT_Warray_bounds:
     case OPT_Warray_bounds_:
     case OPT_Wformat_overflow_:
     case OPT_Wformat_truncation_:
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index fbf448e045d..7af85b86f75 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -182,7 +182,7 @@ bool
 array_bounds_checker::check_array_ref (location_t location, tree ref,
 				       gimple *stmt, bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     /* Return true to have the caller prevent warnings for enclosing
        refs.  */
     return true;
@@ -287,7 +287,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 
   /* Empty array.  */
   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
-    warned = warning_at (location, OPT_Warray_bounds,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is outside array bounds of %qT",
 			 low_sub, artype);
 
@@ -313,7 +313,7 @@ array_bounds_checker::check_array_ref (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,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%E, %E] is outside "
 			     "array bounds of %qT",
 			     low_sub, up_sub, artype);
@@ -323,12 +323,12 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 	   && (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,
+    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,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is below array bounds of %qT",
 			 low_sub, artype);
 
@@ -353,7 +353,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
       /* 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_Warray_bounds_);
 
       if (decl)
 	ref = decl;
@@ -393,7 +393,7 @@ bool
 array_bounds_checker::check_mem_ref (location_t location, tree ref,
 				     bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     return false;
 
   /* The statement used to allocate the array or null.  */
@@ -493,12 +493,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
   if (lboob)
     {
       if (offrange[0] == offrange[1])
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript %wi is outside array bounds "
 			     "of %qT",
 			     offrange[0].to_shwi (), reftype);
       else
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%wi, %wi] is outside "
 			     "array bounds of %qT",
 			     offrange[0].to_shwi (),
@@ -513,7 +513,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
 	backtype = build_array_type_nelts (unsigned_char_type_node,
 					   aref.sizrng[1].to_uhwi ());
 
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %<%T[%wi]%> is partly "
 			   "outside array bounds of %qT",
 			   axstype, offrange[0].to_shwi (), backtype);
@@ -523,7 +523,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       /* TODO: Determine the access from the statement and use it.  */
       aref.inform_access (access_none);
-      suppress_warning (ref, OPT_Warray_bounds);
+      suppress_warning (ref, OPT_Warray_bounds_);
       return true;
     }
 
@@ -536,11 +536,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
 
-      if (warning_at (location, OPT_Warray_bounds,
+      if (warning_at (location, OPT_Warray_bounds_,
 		      "intermediate array offset %wi is outside array bounds "
 		      "of %qT", tmpidx, reftype))
 	{
-	  suppress_warning (ref, OPT_Warray_bounds);
+	  suppress_warning (ref, OPT_Warray_bounds_);
 	  return true;
 	}
     }
@@ -572,7 +572,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	warned = check_mem_ref (location, t, ignore_off_by_one);
 
       if (warned)
-	suppress_warning (t, OPT_Warray_bounds);
+	suppress_warning (t, OPT_Warray_bounds_);
 
       t = TREE_OPERAND (t, 0);
     }
@@ -580,7 +580,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 
   if (TREE_CODE (t) != MEM_REF
       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
-      || warning_suppressed_p (t, OPT_Warray_bounds))
+      || warning_suppressed_p (t, OPT_Warray_bounds_))
     return;
 
   tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
@@ -615,7 +615,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wi is below "
 			   "array bounds of %qT",
 			   idx.to_shwi (), TREE_TYPE (tem));
@@ -629,7 +629,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wu is above "
 			   "array bounds of %qT",
 			   idx.to_uhwi (), TREE_TYPE (tem));
@@ -640,7 +640,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
       if (DECL_P (t))
 	inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
 
-      suppress_warning (t, OPT_Warray_bounds);
+      suppress_warning (t, OPT_Warray_bounds_);
     }
 }
 
@@ -740,7 +740,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
   /* Propagate the no-warning bit to the outer statement to avoid also
      issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
   if (warned)
-    suppress_warning (wi->stmt, OPT_Warray_bounds);
+    suppress_warning (wi->stmt, OPT_Warray_bounds_);
 
   return NULL_TREE;
 }
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index 832456ba6fc..107ba278798 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -1734,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
   if (!oobref)
     return no_warning;
 
-  const opt_code opt = OPT_Warray_bounds;
+  const opt_code opt = OPT_Warray_bounds_;
   /* Return true without issuing a warning.  */
   if (!do_warn)
     return opt;
diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
new file mode 100644
index 00000000000..79112691b63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107787.c
@@ -0,0 +1,13 @@
+/* PR driver/107787 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Werror=array-bounds=1" } */
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+int a[10];     /* { dg-note "while referencing" } */
+
+int* f(void) {
+
+    a[-1] = 0; /* { dg-error "is below array bounds" } */
+
+    return a;
+}
  
Richard Biener Nov. 23, 2022, 8:11 p.m. UTC | #2
On Wed, Nov 23, 2022 at 3:08 PM Iskander Shakirzyanov via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi!
> Sorry for the initially missing description.
> The following patch changes the definition of -Warray-bounds to an Alias to -Warray-bounds=1. This is necessary for the correct use of -Werror=array-bounds=X, for more information see bug report 107787 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107787)
> As I understand, this happens because -Warray-bounds and -Warray-bounds= are declared as 2 different options in common.opt, so when diagnostic_classify_diagnostic() (opts-common.cc:1880) is called, DK_ERROR is set for the -Warray-bounds= option, but in diagnostic_report_diagnostic() (diagnostic.cc:1446) through warning_at() passes opt_index of -Warray-bounds, so information about DK_ERROR is lost.

How did you test the patch?  If you bootstrapped it and ran the
testsuite then it's OK.

Thanks,
Richard.

>
> From 51559e862d191a1f51cc9af11f0d9be5fbc0b43c Mon Sep 17 00:00:00 2001
> From: Iskander Shakirzyanov <iskander@ispras.ru>
> Date: Wed, 23 Nov 2022 12:26:47 +0000
> Subject: [PATCH] Make Warray-bounds alias to Warray-bounds= [PR107787]
>
>         PR driver/107787
>
> gcc/ChangeLog:
>
>         * common.opt (Warray-bounds): Turn into alias to
>         -Warray-bounds=1.
>         * builtins.cc (warn_array_bounds): Use OPT_Warray_bounds_
>         instead of OPT_Warray_bounds.
>         * diagnostic-spec.cc: Likewise.
>         * gimple-array-bounds.cc: Likewise.
>         * gimple-ssa-warn-restrict.cc: Likewise.
>
> gcc/testsuite/ChangeLog:
>
>         * pr107787.c: New test.
>
> gcc/c-family/ChangeLog:
>
>         * c-common.cc (warn_array_bounds): Use OPT_Warray_bounds_
>         instead of OPT_Warray_bounds.
> ---
>  gcc/builtins.cc                 |  6 +++---
>  gcc/c-family/c-common.cc        |  4 ++--
>  gcc/common.opt                  |  2 +-
>  gcc/diagnostic-spec.cc          |  1 -
>  gcc/gimple-array-bounds.cc      | 38 ++++++++++++++++-----------------
>  gcc/gimple-ssa-warn-restrict.cc |  2 +-
>  gcc/testsuite/gcc.dg/pr107787.c | 13 +++++++++++
>  7 files changed, 39 insertions(+), 27 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr107787.c
>
> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> index 4dc1ca672b2..02c4fefa86f 100644
> --- a/gcc/builtins.cc
> +++ b/gcc/builtins.cc
> @@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
>      {
>        /* Suppress multiple warnings for propagated constant strings.  */
>        if (only_value != 2
> -         && !warning_suppressed_p (arg, OPT_Warray_bounds)
> -         && warning_at (loc, OPT_Warray_bounds,
> +         && !warning_suppressed_p (arg, OPT_Warray_bounds_)
> +         && warning_at (loc, OPT_Warray_bounds_,
>                          "offset %qwi outside bounds of constant string",
>                          eltoff))
>         {
>           if (decl)
>             inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
> -         suppress_warning (arg, OPT_Warray_bounds);
> +         suppress_warning (arg, OPT_Warray_bounds_);
>         }
>        return NULL_TREE;
>      }
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index 6f1f21bc4c1..b0da6886ccf 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
>                      definition thereof.  */
>                   if (TREE_CODE (v) == ARRAY_REF
>                       || TREE_CODE (v) == COMPONENT_REF)
> -                   warning (OPT_Warray_bounds,
> +                   warning (OPT_Warray_bounds_,
>                              "index %E denotes an offset "
>                              "greater than size of %qT",
>                              t, TREE_TYPE (TREE_OPERAND (expr, 0)));
> @@ -8534,7 +8534,7 @@ convert_vector_to_array_for_subscript (location_t loc,
>        if (TREE_CODE (index) == INTEGER_CST)
>          if (!tree_fits_uhwi_p (index)
>             || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
> -          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
> +          warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
>
>        /* We are building an ARRAY_REF so mark the vector as addressable
>           to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 26e9d1cc4e7..e475d6e56eb 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -539,7 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
>  Warn if a loop with constant number of iterations triggers undefined behavior.
>
>  Warray-bounds
> -Common Var(warn_array_bounds) Warning
> +Common Alias(Warray-bounds=, 1, 0) Warning
>  Warn if an array is accessed out of bounds.
>
>  Warray-bounds=
> diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
> index aece89619e7..7a03fc493e6 100644
> --- a/gcc/diagnostic-spec.cc
> +++ b/gcc/diagnostic-spec.cc
> @@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
>        break;
>
>        /* Access warning group.  */
> -    case OPT_Warray_bounds:
>      case OPT_Warray_bounds_:
>      case OPT_Wformat_overflow_:
>      case OPT_Wformat_truncation_:
> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
> index fbf448e045d..7af85b86f75 100644
> --- a/gcc/gimple-array-bounds.cc
> +++ b/gcc/gimple-array-bounds.cc
> @@ -182,7 +182,7 @@ bool
>  array_bounds_checker::check_array_ref (location_t location, tree ref,
>                                        gimple *stmt, bool ignore_off_by_one)
>  {
> -  if (warning_suppressed_p (ref, OPT_Warray_bounds))
> +  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
>      /* Return true to have the caller prevent warnings for enclosing
>         refs.  */
>      return true;
> @@ -287,7 +287,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>
>    /* Empty array.  */
>    if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
> -    warned = warning_at (location, OPT_Warray_bounds,
> +    warned = warning_at (location, OPT_Warray_bounds_,
>                          "array subscript %E is outside array bounds of %qT",
>                          low_sub, artype);
>
> @@ -313,7 +313,7 @@ array_bounds_checker::check_array_ref (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,
> +       warned = warning_at (location, OPT_Warray_bounds_,
>                              "array subscript [%E, %E] is outside "
>                              "array bounds of %qT",
>                              low_sub, up_sub, artype);
> @@ -323,12 +323,12 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>            && (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,
> +    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,
> +    warned = warning_at (location, OPT_Warray_bounds_,
>                          "array subscript %E is below array bounds of %qT",
>                          low_sub, artype);
>
> @@ -353,7 +353,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>        /* 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_Warray_bounds_);
>
>        if (decl)
>         ref = decl;
> @@ -393,7 +393,7 @@ bool
>  array_bounds_checker::check_mem_ref (location_t location, tree ref,
>                                      bool ignore_off_by_one)
>  {
> -  if (warning_suppressed_p (ref, OPT_Warray_bounds))
> +  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
>      return false;
>
>    /* The statement used to allocate the array or null.  */
> @@ -493,12 +493,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>    if (lboob)
>      {
>        if (offrange[0] == offrange[1])
> -       warned = warning_at (location, OPT_Warray_bounds,
> +       warned = warning_at (location, OPT_Warray_bounds_,
>                              "array subscript %wi is outside array bounds "
>                              "of %qT",
>                              offrange[0].to_shwi (), reftype);
>        else
> -       warned = warning_at (location, OPT_Warray_bounds,
> +       warned = warning_at (location, OPT_Warray_bounds_,
>                              "array subscript [%wi, %wi] is outside "
>                              "array bounds of %qT",
>                              offrange[0].to_shwi (),
> @@ -513,7 +513,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>         backtype = build_array_type_nelts (unsigned_char_type_node,
>                                            aref.sizrng[1].to_uhwi ());
>
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>                            "array subscript %<%T[%wi]%> is partly "
>                            "outside array bounds of %qT",
>                            axstype, offrange[0].to_shwi (), backtype);
> @@ -523,7 +523,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>      {
>        /* TODO: Determine the access from the statement and use it.  */
>        aref.inform_access (access_none);
> -      suppress_warning (ref, OPT_Warray_bounds);
> +      suppress_warning (ref, OPT_Warray_bounds_);
>        return true;
>      }
>
> @@ -536,11 +536,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>      {
>        HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
>
> -      if (warning_at (location, OPT_Warray_bounds,
> +      if (warning_at (location, OPT_Warray_bounds_,
>                       "intermediate array offset %wi is outside array bounds "
>                       "of %qT", tmpidx, reftype))
>         {
> -         suppress_warning (ref, OPT_Warray_bounds);
> +         suppress_warning (ref, OPT_Warray_bounds_);
>           return true;
>         }
>      }
> @@ -572,7 +572,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>         warned = check_mem_ref (location, t, ignore_off_by_one);
>
>        if (warned)
> -       suppress_warning (t, OPT_Warray_bounds);
> +       suppress_warning (t, OPT_Warray_bounds_);
>
>        t = TREE_OPERAND (t, 0);
>      }
> @@ -580,7 +580,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>
>    if (TREE_CODE (t) != MEM_REF
>        || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
> -      || warning_suppressed_p (t, OPT_Warray_bounds))
> +      || warning_suppressed_p (t, OPT_Warray_bounds_))
>      return;
>
>    tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
> @@ -615,7 +615,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>           dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
>           fprintf (dump_file, "\n");
>         }
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>                            "array subscript %wi is below "
>                            "array bounds of %qT",
>                            idx.to_shwi (), TREE_TYPE (tem));
> @@ -629,7 +629,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>           dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
>           fprintf (dump_file, "\n");
>         }
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>                            "array subscript %wu is above "
>                            "array bounds of %qT",
>                            idx.to_uhwi (), TREE_TYPE (tem));
> @@ -640,7 +640,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>        if (DECL_P (t))
>         inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
>
> -      suppress_warning (t, OPT_Warray_bounds);
> +      suppress_warning (t, OPT_Warray_bounds_);
>      }
>  }
>
> @@ -740,7 +740,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
>    /* Propagate the no-warning bit to the outer statement to avoid also
>       issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
>    if (warned)
> -    suppress_warning (wi->stmt, OPT_Warray_bounds);
> +    suppress_warning (wi->stmt, OPT_Warray_bounds_);
>
>    return NULL_TREE;
>  }
> diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
> index 832456ba6fc..107ba278798 100644
> --- a/gcc/gimple-ssa-warn-restrict.cc
> +++ b/gcc/gimple-ssa-warn-restrict.cc
> @@ -1734,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
>    if (!oobref)
>      return no_warning;
>
> -  const opt_code opt = OPT_Warray_bounds;
> +  const opt_code opt = OPT_Warray_bounds_;
>    /* Return true without issuing a warning.  */
>    if (!do_warn)
>      return opt;
> diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
> new file mode 100644
> index 00000000000..79112691b63
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr107787.c
> @@ -0,0 +1,13 @@
> +/* PR driver/107787 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Werror=array-bounds=1" } */
> +/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
> +
> +int a[10];     /* { dg-note "while referencing" } */
> +
> +int* f(void) {
> +
> +    a[-1] = 0; /* { dg-error "is below array bounds" } */
> +
> +    return a;
> +}
> --
> 2.25.1
>
  
Franz Sirl Nov. 24, 2022, 9:54 a.m. UTC | #3
Am 2022-11-23 um 21:11 schrieb Richard Biener via Gcc-patches:
> On Wed, Nov 23, 2022 at 3:08 PM Iskander Shakirzyanov via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>>
>> Hi!
>> Sorry for the initially missing description.
>> The following patch changes the definition of -Warray-bounds to an Alias to -Warray-bounds=1. This is necessary for the correct use of -Werror=array-bounds=X, for more information see bug report 107787 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107787)
>> As I understand, this happens because -Warray-bounds and -Warray-bounds= are declared as 2 different options in common.opt, so when diagnostic_classify_diagnostic() (opts-common.cc:1880) is called, DK_ERROR is set for the -Warray-bounds= option, but in diagnostic_report_diagnostic() (diagnostic.cc:1446) through warning_at() passes opt_index of -Warray-bounds, so information about DK_ERROR is lost.
> 
> How did you test the patch?  If you bootstrapped it and ran the
> testsuite then it's OK.

Hi,

I'm pretty sure the testsuite will have regressions, as I have a very 
similar patch lying around that needs these testsuite changes. I also
added some modified tests that check that -Werror=array-bounds=X works 
as expected (which it didn't before). This also shows nicely why I don't 
like warnings with levels, what if I want -Werror=array-bounds=2 + 
-Warray-bounds=1?

The reason (besides lack of time) I didn't submit that patch yet, is 
that I wanted to check if the tool to process common.opt can be changed 
to detect warnings with duplicated warning variables. Because I think at 
least -Wuse-after-free= and Wattributes= have the same problem.

BTW, is the duplicated warning description "Warn if an array is accessed 
out of bounds." needed or not with Alias()? There are examples either 
way in common.opt.

I've attached my patch, feel free to integrate the testsuite changes.

Franz
From 9bfefe2082f55f2ad2cd19beedbfeaf9bd20fb4a Mon Sep 17 00:00:00 2001
From: Franz Sirl <franz.sirl-kernel@lauterbach.com>
Date: Thu, 8 Jul 2021 10:25:00 +0200
Subject: [PATCH 08/11] Unify -Warray-bounds/-Warray-bounds= warning variables.

---
 gcc/builtins.cc                         |   6 +-
 gcc/c-family/c-common.cc                |   6 +-
 gcc/common.opt                          |   3 +-
 gcc/diagnostic-spec.cc                  |   1 -
 gcc/gimple-array-bounds.cc              |  38 +++---
 gcc/gimple-ssa-warn-restrict.cc         |   2 +-
 gcc/testsuite/gcc.dg/Warray-bounds-34.c |   2 +-
 gcc/testsuite/gcc.dg/Warray-bounds-43.c |   6 +-
 gcc/testsuite/gcc.dg/Warray-bounds-93.c | 103 ++++++++++++++++
 gcc/testsuite/gcc.dg/Warray-bounds-94.c | 149 ++++++++++++++++++++++++
 10 files changed, 283 insertions(+), 33 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-93.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-94.c

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4dc1ca672b2..02c4fefa86f 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
     {
       /* Suppress multiple warnings for propagated constant strings.  */
       if (only_value != 2
-	  && !warning_suppressed_p (arg, OPT_Warray_bounds)
-	  && warning_at (loc, OPT_Warray_bounds,
+	  && !warning_suppressed_p (arg, OPT_Warray_bounds_)
+	  && warning_at (loc, OPT_Warray_bounds_,
 			 "offset %qwi outside bounds of constant string",
 			 eltoff))
 	{
 	  if (decl)
 	    inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
-	  suppress_warning (arg, OPT_Warray_bounds);
+	  suppress_warning (arg, OPT_Warray_bounds_);
 	}
       return NULL_TREE;
     }
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 71507d4cb0a..cf423d384f6 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
 		     definition thereof.  */
 		  if (TREE_CODE (v) == ARRAY_REF
 		      || TREE_CODE (v) == COMPONENT_REF)
-		    warning (OPT_Warray_bounds,
+		    warning (OPT_Warray_bounds_,
 			     "index %E denotes an offset "
 			     "greater than size of %qT",
 			     t, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -8530,9 +8530,9 @@ convert_vector_to_array_for_subscript (location_t loc,
 
       index = fold_for_warn (index);
       if (TREE_CODE (index) == INTEGER_CST)
-        if (!tree_fits_uhwi_p (index)
+	if (!tree_fits_uhwi_p (index)
 	    || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
-          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+	  warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
 
       /* We are building an ARRAY_REF so mark the vector as addressable
          to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
diff --git a/gcc/common.opt b/gcc/common.opt
index 26e9d1cc4e7..c2ed944a57f 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -539,8 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
 Warn if a loop with constant number of iterations triggers undefined behavior.
 
 Warray-bounds
-Common Var(warn_array_bounds) Warning
-Warn if an array is accessed out of bounds.
+Common Warning Alias(Warray-bounds=,1,0)
 
 Warray-bounds=
 Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning IntegerRange(0, 2)
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index aece89619e7..7a03fc493e6 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
       break;
 
       /* Access warning group.  */
-    case OPT_Warray_bounds:
     case OPT_Warray_bounds_:
     case OPT_Wformat_overflow_:
     case OPT_Wformat_truncation_:
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index fbf448e045d..7af85b86f75 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -182,7 +182,7 @@ bool
 array_bounds_checker::check_array_ref (location_t location, tree ref,
 				       gimple *stmt, bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     /* Return true to have the caller prevent warnings for enclosing
        refs.  */
     return true;
@@ -287,7 +287,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 
   /* Empty array.  */
   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
-    warned = warning_at (location, OPT_Warray_bounds,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is outside array bounds of %qT",
 			 low_sub, artype);
 
@@ -313,7 +313,7 @@ array_bounds_checker::check_array_ref (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,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%E, %E] is outside "
 			     "array bounds of %qT",
 			     low_sub, up_sub, artype);
@@ -323,12 +323,12 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 	   && (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,
+    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,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is below array bounds of %qT",
 			 low_sub, artype);
 
@@ -353,7 +353,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
       /* 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_Warray_bounds_);
 
       if (decl)
 	ref = decl;
@@ -393,7 +393,7 @@ bool
 array_bounds_checker::check_mem_ref (location_t location, tree ref,
 				     bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     return false;
 
   /* The statement used to allocate the array or null.  */
@@ -493,12 +493,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
   if (lboob)
     {
       if (offrange[0] == offrange[1])
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript %wi is outside array bounds "
 			     "of %qT",
 			     offrange[0].to_shwi (), reftype);
       else
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%wi, %wi] is outside "
 			     "array bounds of %qT",
 			     offrange[0].to_shwi (),
@@ -513,7 +513,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
 	backtype = build_array_type_nelts (unsigned_char_type_node,
 					   aref.sizrng[1].to_uhwi ());
 
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %<%T[%wi]%> is partly "
 			   "outside array bounds of %qT",
 			   axstype, offrange[0].to_shwi (), backtype);
@@ -523,7 +523,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       /* TODO: Determine the access from the statement and use it.  */
       aref.inform_access (access_none);
-      suppress_warning (ref, OPT_Warray_bounds);
+      suppress_warning (ref, OPT_Warray_bounds_);
       return true;
     }
 
@@ -536,11 +536,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
 
-      if (warning_at (location, OPT_Warray_bounds,
+      if (warning_at (location, OPT_Warray_bounds_,
 		      "intermediate array offset %wi is outside array bounds "
 		      "of %qT", tmpidx, reftype))
 	{
-	  suppress_warning (ref, OPT_Warray_bounds);
+	  suppress_warning (ref, OPT_Warray_bounds_);
 	  return true;
 	}
     }
@@ -572,7 +572,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	warned = check_mem_ref (location, t, ignore_off_by_one);
 
       if (warned)
-	suppress_warning (t, OPT_Warray_bounds);
+	suppress_warning (t, OPT_Warray_bounds_);
 
       t = TREE_OPERAND (t, 0);
     }
@@ -580,7 +580,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 
   if (TREE_CODE (t) != MEM_REF
       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
-      || warning_suppressed_p (t, OPT_Warray_bounds))
+      || warning_suppressed_p (t, OPT_Warray_bounds_))
     return;
 
   tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
@@ -615,7 +615,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wi is below "
 			   "array bounds of %qT",
 			   idx.to_shwi (), TREE_TYPE (tem));
@@ -629,7 +629,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wu is above "
 			   "array bounds of %qT",
 			   idx.to_uhwi (), TREE_TYPE (tem));
@@ -640,7 +640,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
       if (DECL_P (t))
 	inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
 
-      suppress_warning (t, OPT_Warray_bounds);
+      suppress_warning (t, OPT_Warray_bounds_);
     }
 }
 
@@ -740,7 +740,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
   /* Propagate the no-warning bit to the outer statement to avoid also
      issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
   if (warned)
-    suppress_warning (wi->stmt, OPT_Warray_bounds);
+    suppress_warning (wi->stmt, OPT_Warray_bounds_);
 
   return NULL_TREE;
 }
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index 832456ba6fc..107ba278798 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -1734,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
   if (!oobref)
     return no_warning;
 
-  const opt_code opt = OPT_Warray_bounds;
+  const opt_code opt = OPT_Warray_bounds_;
   /* Return true without issuing a warning.  */
   if (!do_warn)
     return opt;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-34.c b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
index cea7c4b32a2..1b2a098ad86 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-34.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
@@ -7,7 +7,7 @@ int x;
 
 inline void foo (int i)
 {
-  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds]" } */
+  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds" } */
 }
 
 int bar (void)
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
index 0f521a7250d..43a83315787 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -19,7 +19,7 @@ NOIPA int g2 (int i)
 
   sink (p0, p1, p2);
 
-  return p2[8];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p2[8];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g3 (int i)
@@ -33,7 +33,7 @@ NOIPA int g3 (int i)
 
   sink (p0, p1, p2, p3);
 
-  return p3[7];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p3[7];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g4 (int i)
@@ -48,7 +48,7 @@ NOIPA int g4 (int i)
 
   sink (p0, p1, p2, p3, p4);
 
-  return p4[6];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p4[6];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g5 (int i)
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-93.c b/gcc/testsuite/gcc.dg/Warray-bounds-93.c
new file mode 100644
index 00000000000..0822411179b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-93.c
@@ -0,0 +1,103 @@
+/* copied from gcc.dg/Warray-bounds.c to test -Werror=array-bounds=1 functionality.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-array-bounds -Werror=array-bounds=1" } */
+
+int a[10];
+
+static inline int n(void) {
+    __SIZE_TYPE__ strlen(const char *s);
+    return strlen("12345");
+}
+
+void g(int *p);
+void h(int p);
+
+void bar (void *);
+
+int* f(void) {
+    int b[10];
+    int i;
+    struct {
+       int c[10];
+    } c;
+
+    a[-1] = 0;             /* { dg-error "6:array subscript" } */
+    a[ 0] = 0;
+    a[ 1] = 0;
+
+
+    a[ 9] = 0;
+    a[10] = 0;             /* { dg-error "6:array subscript" } */
+    a[11] = 0;             /* { dg-error "6:array subscript" } */
+    bar (a);
+    a[2 * n() - 11] = 1;    /* { dg-error "6:array subscript" } */
+    a[2 * n() - 10] = 1;
+    a[2 * n() -  1] = 1;
+    a[2 * n() -  0] = 1;    /* { dg-error "6:array subscript" } */
+    bar (a);
+
+    b[-1] = 0;             /* { dg-error "6:array subscript" } */
+    b[ 0] = 0;
+    b[ 1] = 0;
+    b[ 9] = 0;
+    b[10] = 0;             /* { dg-error "6:array subscript" } */
+    b[11] = 0;             /* { dg-error "6:array subscript" } */
+    bar (b);
+    b[2 * n() - 11] = 1;    /* { dg-error "6:array subscript" } */
+    b[2 * n() - 10] = 1;
+    b[2 * n() -  1] = 1;
+    b[2 * n() -  0] = 1;    /* { dg-error "array subscript" } */
+
+    c.c[-1] = 0;           /* { dg-error "8:array subscript" } */
+    c.c[ 0] = 0;
+    c.c[ 1] = 0;
+    c.c[ 9] = 0;
+    c.c[10] = 0;           /* { dg-error "8:array subscript" } */
+    c.c[11] = 0;           /* { dg-error "8:array subscript" } */
+    bar (&c);
+    c.c[2 * n() - 11] = 1;  /* { dg-error "8:array subscript" } */
+    c.c[2 * n() - 10] = 1;
+    c.c[2 * n() -  1] = 1;
+    c.c[2 * n() -  0] = 1;  /* { dg-error "8:array subscript" } */
+
+    g(&a[8]);
+    g(&a[9]);
+    g(&a[10]);
+    g(&a[11]);             /* { dg-error "array subscript" } */
+    g(&a[-30]+10);             /* { dg-error "array subscript" } */
+    g(&a[-30]+30);
+
+    g(&b[10]);
+    g(&c.c[10]);
+    g(&b[11]);             /* { dg-error "array subscript" } */
+    g(&c.c[11]);           /* { dg-error "array subscript" } */
+
+    g(&a[0]);
+    g(&b[0]);
+    g(&c.c[0]);
+
+    g(&a[-1]);             /* { dg-error "array subscript" } */
+    g(&b[-1]);             /* { dg-error "array subscript" } */
+    h(sizeof a[-1]);
+    h(sizeof a[10]);
+    h(sizeof b[-1]);
+    h(sizeof b[10]);
+    h(sizeof c.c[-1]);
+    h(sizeof c.c[10]);
+
+    if (10 < 10)
+       a[10] = 0;
+    if (10 < 10)
+       b[10] = 0;
+    if (-1 >= 0)
+       c.c[-1] = 0;
+
+    for (i = 20; i < 30; ++i)
+             a[i] = 1;       /* { dg-error "15:array subscript" } */
+
+    bar (b);
+    bar (&c);
+    return a;
+}
+
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-94.c b/gcc/testsuite/gcc.dg/Warray-bounds-94.c
new file mode 100644
index 00000000000..137d2aaf109
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-94.c
@@ -0,0 +1,149 @@
+/* copied from gcc.dg/Warray-bounds-29.c to test -Werror=array-bounds=2 functionality
+   { dg-do compile }
+   { dg-options "-O2 -Wno-array-bounds -Werror=array-bounds=2 -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define MAX DIFF_MAX
+#define MIN DIFF_MIN
+
+typedef __WCHAR_TYPE__ wchar_t;
+
+void sink (int, ...);
+
+#define T(expr)   sink (0, expr)
+
+void test_narrow (void)
+{
+  int i = SR (1, 2);
+
+  const char *p0 = "12";
+  const char *p1 = p0 + i;    /* points at '2' or beyond */
+  const char *p2 = p1 + i;    /* points at '\0' or beyond */
+  const char *p3 = p2 + i;    /* points just past the end */
+  const char *p4 = p3 + i;    /* invalid */
+
+  T (p0[-1]);                 /* { dg-error "array subscript \(-1|\[0-9\]+) is outside array bounds of .char\\\[3]." } */
+  T (p0[0]);
+  T (p0[1]);
+  T (p0[2]);
+  T (p0[3]);                  /* { dg-error "array subscript 3 is outside array bounds of .char\\\[3]." } */
+
+  T (&p0[-1]);                /* { dg-error "array subscript \(-1|\[0-9\]+) is \(above|below|outside\) array bounds of .char\\\[3]." } */
+  T (&p0[0]);
+  T (&p0[1]);
+  T (&p0[2]);
+  T (&p0[3]);
+  T (&p0[4]);                 /* { dg-error "array subscript 4 is \(above|outside\) array bounds of .char\\\[3]." } */
+
+  T (p1[-3]);                 /* { dg-error "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." } */
+  T (p1[-2]);
+  T (p1[-1]);
+  T (p1[ 0]);
+  T (p1[ 1]);
+  T (p1[ 2]);                 /* { dg-error "array subscript 3 is outside array bounds of .char\\\[3]." } */
+  T (p1[ 3]);                 /* { dg-error "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
+
+  T (&p1[-3]);                /* { dg-error "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
+  T (&p1[-2]);
+  T (&p1[-1]);
+  T (&p1[ 0]);
+  T (&p1[ 1]);
+  T (&p1[ 2]);
+  T (&p1[ 3]);                /* { dg-error "array subscript \\\[4, 6] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
+
+  T (p2[-4]);                 /* { dg-error "subscript \\\[-2, -1\\\] is outside array bounds of .char\\\[3]." } */
+  T (p2[-3]);
+  T (p2[-2]);
+  T (p2[-1]);
+  T (p2[ 0]);
+
+  /* Even though the lower bound of p3's offsets is in bounds, in order
+     to subtract 4 from p3 and get a dereferenceable pointer its value
+     would have to be out-of-bounds.  */
+  T (p3[-4]);                 /* { dg-error "array subscript -1 is outside array bounds of .char\\\[3]." } */
+  T (p3[-3]);
+  T (p3[-2]);
+  T (p3[-1]);
+  T (p3[ 0]);                 /* { dg-error "array subscript 3 is outside array bounds of .char\\\[3]." } */
+
+  T (p4[-4]);                 /* { dg-error "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
+  T (p4[-3]);                 /* { dg-error "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
+  T (p4[-2]);                 /* { dg-error "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
+
+  /* The final subscripts below are invalid.  */
+  T (p4[-1]);                 /* { dg-error "array subscript 3 is outside array bounds of .char\\\[3]." } */
+  T (p4[ 0]);                 /* { dg-error "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
+}
+
+
+void test_narrow_vflow (void)
+{
+  int i = SR (DIFF_MAX - 2, DIFF_MAX);
+  int j = SR (1, DIFF_MAX);
+
+  const char *p0 = "123";
+  const char *p1 = p0 + i;    /* points at '2' or beyond */
+  const char *p2 = p1 + i;    /* points at '\0' or beyond */
+  const char *p3 = p2 + i;    /* points just past the end */
+  const char *p4 = p3 + i;    /* invalid */
+}
+
+
+void test_wide (void)
+{
+  int i = SR (1, 2);
+
+  const wchar_t *p0 = L"123";
+  const wchar_t *p1 = p0 + i;    /* points at L'2' or beyond */
+  const wchar_t *p2 = p1 + i;    /* points at L'3' or beyond */
+  const wchar_t *p3 = p2 + i;    /* points at L'\0' or beyond */
+  const wchar_t *p4 = p3 + i;    /* points just past the end */
+  const wchar_t *p5 = p4 + i;    /* invalid */
+
+  T (p0[0]);
+  T (p0[1]);
+  T (p0[2]);
+  T (p0[3]);
+  T (p0[4]);                  /* { dg-error "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
+
+  T (p1[-1]);
+  T (p1[ 0]);
+  T (p1[ 1]);
+  T (p1[ 2]);
+  T (p1[ 3]);                  /* { dg-error "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
+
+  T (&p1[-1]);
+  T (&p1[ 0]);
+  T (&p1[ 1]);
+  T (&p1[ 2]);
+  T (&p1[ 3]);
+  T (&p1[ 4]);                 /* { dg-error "array subscript \\\[5, 6] is outside array bounds of .\[a-z \]+\\\[4]." "bug" { xfail *-*-* } } */
+
+  T (p2[-5]);                 /* { dg-error "array subscript \\\[-3, -1] is outside array bounds of .\[a-z \]+\\\[4]." } */
+  T (p2[-4]);
+  T (p2[-3]);
+  T (p2[-2]);
+  T (p2[-1]);
+  T (p2[ 0]);
+
+  /* Even though the lower bound of p3's offsets is in bounds, in order
+     to subtract 5 from p3 and get a dereferenceable pointer its value
+     would have to be out-of-bounds.  */
+  T (p3[-5]);                 /* { dg-error "array subscript \\\[-2, -1\\\] is outside array bounds of .\[a-z \]+\\\[4]." } */
+  T (p3[-4]);
+  T (p3[-3]);
+  T (p3[-2]);
+  T (p3[-1]);
+  T (p3[ 0]);
+  T (p3[ 1]);                 /* { dg-error "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
+
+  T (p4[-5]);                 /* { dg-error "array subscript -1 is outside array bounds of .\[a-z \]+\\\[4]." } */
+  T (p4[-4]);
+  T (p4[-3]);
+  T (p4[-2]);
+  T (p4[-1]);
+  T (p4[ 0]);                 /* { dg-error "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
+}
+
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
  
Iskander Shakirzyanov Nov. 24, 2022, 3:27 p.m. UTC | #4
>> How did you test the patch? If you bootstrapped it and ran the
>> testsuite then it's OK.
Yes, i ran testsuite and  bootstrapped and everything seemed OK, but i missed fail of tests gcc.dg/Warray-bounds-34.c and gcc.dg/Warray-bounds-43.c, so Franz is right. After that I fixed the regexps in dg directives and now everything seems OK.  

> I'm pretty sure the testsuite will have regressions, as I have a very similar patch lying around that needs these testsuite changes.

You are right, thank you. I missed this, attaching corrected version of patch.

> This also shows nicely why I don't like warnings with levels, what if I want -Werror=array-bounds=2 + -Warray-bounds=1?

I completely agree with you, because I also thought about using -Werror=opt=X + -Wopt=Y, this functionality looks useful. As I know, gcc, while parsing an option with the same OPT,  overwrites the old config of OPT. 

> Because I think at least -Wuse-after-free= and Wattributes= have the same problem.

Yes, looks like this, probably should be fixed too.  

> BTW, is the duplicated warning description "Warn if an array is accessed out of bounds." needed or not with Alias()?

According to other examples in common.opt, duplicated description is not necessary, you are right.

> I've attached my patch, feel free to integrate the testsuite changes.

Thanks, but it seems to me that duplicating existing tests seems redundant to test functionality of -Werror=array-bounds=X.


From bf047e36392dab138db10be2ec257d08c376ada5 Mon Sep 17 00:00:00 2001
From: Iskander Shakirzyanov <iskander@ispras.ru>
Date: Thu, 24 Nov 2022 14:26:59 +0000
Subject: [PATCH] Make Warray-bounds alias to Warray-bounds= [PR107787]

According to documentation the -Werror= option makes the specified warning
into an error and also automatically implies this option. Then it seems that
the behavior of the compiler when specifying -Werror=array-bounds=X should be
the same as specifying "-Werror=array-bounds -Warray-bounds=X", so we expect to
receive array-bounds pass triggers and they must be processed as errors.
In practice, we observe that the array-bounds pass is indeed called, but
its responses are processed as warnings, not errors.
As I understand, this happens because Warray-bounds and Warray-bounds= are
declared as 2 different options in common.opt, so when
diagnostic_classify_diagnostic() is called, DK_ERROR is set for
the Warray-bounds= option, but in diagnostic_report_diagnostic() through
warning_at() passes opt_index of Warray-bounds, so information about
DK_ERROR is lost. Fixed by using Alias() in declaration of
Warray-bounds (similarly as in Wattribute-alias etc.)

PR driver/107787

Co-authored-by: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>

gcc/ChangeLog:

	* common.opt (Warray-bounds): Turn into alias to
	-Warray-bounds=1.
	* builtins.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
	* diagnostic-spec.cc: Likewise.
	* gimple-array-bounds.cc: Likewise.
	* gimple-ssa-warn-restrict.cc: Likewise.

gcc/testsuite/ChangeLog:

	* gcc.dg/Warray-bounds-34.c: Correct the regular
	expression for -Warray-bounds=.
	* gcc.dg/Warray-bounds-43.c: Likewise.
	* gcc.dg/pr107787.c: New test.

gcc/c-family/ChangeLog:

	* c-common.cc (warn_array_bounds): Use OPT_Warray_bounds_
	instead of OPT_Warray_bounds.
---
 gcc/builtins.cc                         |  6 ++--
 gcc/c-family/c-common.cc                |  4 +--
 gcc/common.opt                          |  3 +-
 gcc/diagnostic-spec.cc                  |  1 -
 gcc/gimple-array-bounds.cc              | 38 ++++++++++++-------------
 gcc/gimple-ssa-warn-restrict.cc         |  2 +-
 gcc/testsuite/gcc.dg/Warray-bounds-34.c |  2 +-
 gcc/testsuite/gcc.dg/Warray-bounds-43.c |  6 ++--
 gcc/testsuite/gcc.dg/pr107787.c         | 13 +++++++++
 9 files changed, 43 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr107787.c

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4dc1ca672b2..02c4fefa86f 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
     {
       /* Suppress multiple warnings for propagated constant strings.  */
       if (only_value != 2
-	  && !warning_suppressed_p (arg, OPT_Warray_bounds)
-	  && warning_at (loc, OPT_Warray_bounds,
+	  && !warning_suppressed_p (arg, OPT_Warray_bounds_)
+	  && warning_at (loc, OPT_Warray_bounds_,
 			 "offset %qwi outside bounds of constant string",
 			 eltoff))
 	{
 	  if (decl)
 	    inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
-	  suppress_warning (arg, OPT_Warray_bounds);
+	  suppress_warning (arg, OPT_Warray_bounds_);
 	}
       return NULL_TREE;
     }
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 6f1f21bc4c1..b0da6886ccf 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
 		     definition thereof.  */
 		  if (TREE_CODE (v) == ARRAY_REF
 		      || TREE_CODE (v) == COMPONENT_REF)
-		    warning (OPT_Warray_bounds,
+		    warning (OPT_Warray_bounds_,
 			     "index %E denotes an offset "
 			     "greater than size of %qT",
 			     t, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -8534,7 +8534,7 @@ convert_vector_to_array_for_subscript (location_t loc,
       if (TREE_CODE (index) == INTEGER_CST)
         if (!tree_fits_uhwi_p (index)
 	    || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
-          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+          warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
 
       /* We are building an ARRAY_REF so mark the vector as addressable
          to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
diff --git a/gcc/common.opt b/gcc/common.opt
index 26e9d1cc4e7..f91b631f257 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -539,8 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
 Warn if a loop with constant number of iterations triggers undefined behavior.
 
 Warray-bounds
-Common Var(warn_array_bounds) Warning
-Warn if an array is accessed out of bounds.
+Common Alias(Warray-bounds=, 1, 0) Warning
 
 Warray-bounds=
 Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning IntegerRange(0, 2)
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index aece89619e7..7a03fc493e6 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
       break;
 
       /* Access warning group.  */
-    case OPT_Warray_bounds:
     case OPT_Warray_bounds_:
     case OPT_Wformat_overflow_:
     case OPT_Wformat_truncation_:
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index fbf448e045d..7af85b86f75 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -182,7 +182,7 @@ bool
 array_bounds_checker::check_array_ref (location_t location, tree ref,
 				       gimple *stmt, bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     /* Return true to have the caller prevent warnings for enclosing
        refs.  */
     return true;
@@ -287,7 +287,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 
   /* Empty array.  */
   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
-    warned = warning_at (location, OPT_Warray_bounds,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is outside array bounds of %qT",
 			 low_sub, artype);
 
@@ -313,7 +313,7 @@ array_bounds_checker::check_array_ref (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,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%E, %E] is outside "
 			     "array bounds of %qT",
 			     low_sub, up_sub, artype);
@@ -323,12 +323,12 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 	   && (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,
+    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,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is below array bounds of %qT",
 			 low_sub, artype);
 
@@ -353,7 +353,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
       /* 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_Warray_bounds_);
 
       if (decl)
 	ref = decl;
@@ -393,7 +393,7 @@ bool
 array_bounds_checker::check_mem_ref (location_t location, tree ref,
 				     bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     return false;
 
   /* The statement used to allocate the array or null.  */
@@ -493,12 +493,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
   if (lboob)
     {
       if (offrange[0] == offrange[1])
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript %wi is outside array bounds "
 			     "of %qT",
 			     offrange[0].to_shwi (), reftype);
       else
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%wi, %wi] is outside "
 			     "array bounds of %qT",
 			     offrange[0].to_shwi (),
@@ -513,7 +513,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
 	backtype = build_array_type_nelts (unsigned_char_type_node,
 					   aref.sizrng[1].to_uhwi ());
 
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %<%T[%wi]%> is partly "
 			   "outside array bounds of %qT",
 			   axstype, offrange[0].to_shwi (), backtype);
@@ -523,7 +523,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       /* TODO: Determine the access from the statement and use it.  */
       aref.inform_access (access_none);
-      suppress_warning (ref, OPT_Warray_bounds);
+      suppress_warning (ref, OPT_Warray_bounds_);
       return true;
     }
 
@@ -536,11 +536,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
 
-      if (warning_at (location, OPT_Warray_bounds,
+      if (warning_at (location, OPT_Warray_bounds_,
 		      "intermediate array offset %wi is outside array bounds "
 		      "of %qT", tmpidx, reftype))
 	{
-	  suppress_warning (ref, OPT_Warray_bounds);
+	  suppress_warning (ref, OPT_Warray_bounds_);
 	  return true;
 	}
     }
@@ -572,7 +572,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	warned = check_mem_ref (location, t, ignore_off_by_one);
 
       if (warned)
-	suppress_warning (t, OPT_Warray_bounds);
+	suppress_warning (t, OPT_Warray_bounds_);
 
       t = TREE_OPERAND (t, 0);
     }
@@ -580,7 +580,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 
   if (TREE_CODE (t) != MEM_REF
       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
-      || warning_suppressed_p (t, OPT_Warray_bounds))
+      || warning_suppressed_p (t, OPT_Warray_bounds_))
     return;
 
   tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
@@ -615,7 +615,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wi is below "
 			   "array bounds of %qT",
 			   idx.to_shwi (), TREE_TYPE (tem));
@@ -629,7 +629,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wu is above "
 			   "array bounds of %qT",
 			   idx.to_uhwi (), TREE_TYPE (tem));
@@ -640,7 +640,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
       if (DECL_P (t))
 	inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
 
-      suppress_warning (t, OPT_Warray_bounds);
+      suppress_warning (t, OPT_Warray_bounds_);
     }
 }
 
@@ -740,7 +740,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
   /* Propagate the no-warning bit to the outer statement to avoid also
      issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
   if (warned)
-    suppress_warning (wi->stmt, OPT_Warray_bounds);
+    suppress_warning (wi->stmt, OPT_Warray_bounds_);
 
   return NULL_TREE;
 }
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index 832456ba6fc..107ba278798 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -1734,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
   if (!oobref)
     return no_warning;
 
-  const opt_code opt = OPT_Warray_bounds;
+  const opt_code opt = OPT_Warray_bounds_;
   /* Return true without issuing a warning.  */
   if (!do_warn)
     return opt;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-34.c b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
index cea7c4b32a2..1b2a098ad86 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-34.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
@@ -7,7 +7,7 @@ int x;
 
 inline void foo (int i)
 {
-  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds]" } */
+  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds" } */
 }
 
 int bar (void)
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
index 0f521a7250d..43a83315787 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -19,7 +19,7 @@ NOIPA int g2 (int i)
 
   sink (p0, p1, p2);
 
-  return p2[8];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p2[8];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g3 (int i)
@@ -33,7 +33,7 @@ NOIPA int g3 (int i)
 
   sink (p0, p1, p2, p3);
 
-  return p3[7];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p3[7];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g4 (int i)
@@ -48,7 +48,7 @@ NOIPA int g4 (int i)
 
   sink (p0, p1, p2, p3, p4);
 
-  return p4[6];     // { dg-warning "\\\[-Warray-bounds]" }
+  return p4[6];     // { dg-warning "\\\[-Warray-bounds" }
 }
 
 NOIPA int g5 (int i)
diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
new file mode 100644
index 00000000000..922dbff8b2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107787.c
@@ -0,0 +1,13 @@
+/* PR driver/107787 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Werror=array-bounds=1" } */
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+int a[10];     /* { dg-note "while referencing" } */
+
+int* f(void) {
+
+    a[-1] = 0; /* { dg-error "is below array bounds" } */
+
+    return a;
+}
  
Richard Biener Nov. 30, 2022, 7:25 a.m. UTC | #5
On Thu, Nov 24, 2022 at 4:27 PM Iskander Shakirzyanov
<iskander@ispras.ru> wrote:
>
> How did you test the patch? If you bootstrapped it and ran the
> testsuite then it's OK.
>
> Yes, i ran testsuite and  bootstrapped and everything seemed OK, but i missed fail of tests gcc.dg/Warray-bounds-34.c and gcc.dg/Warray-bounds-43.c, so Franz is right. After that I fixed the regexps in dg directives and now everything seems OK.
>
> I'm pretty sure the testsuite will have regressions, as I have a very similar patch lying around that needs these testsuite changes.
>
> You are right, thank you. I missed this, attaching corrected version of patch.
>
> This also shows nicely why I don't like warnings with levels, what if I want -Werror=array-bounds=2 + -Warray-bounds=1?
>
> I completely agree with you, because I also thought about using -Werror=opt=X + -Wopt=Y, this functionality looks useful. As I know, gcc, while parsing an option with the same OPT,  overwrites the old config of OPT.
>
> Because I think at least -Wuse-after-free= and Wattributes= have the same problem.
>
> Yes, looks like this, probably should be fixed too.
>
> BTW, is the duplicated warning description "Warn if an array is accessed out of bounds." needed or not with Alias()?
>
> According to other examples in common.opt, duplicated description is not necessary, you are right.
>
> I've attached my patch, feel free to integrate the testsuite changes.
>
> Thanks, but it seems to me that duplicating existing tests seems redundant to test functionality of -Werror=array-bounds=X.
>
>
> From bf047e36392dab138db10be2ec257d08c376ada5 Mon Sep 17 00:00:00 2001
> From: Iskander Shakirzyanov <iskander@ispras.ru>
> Date: Thu, 24 Nov 2022 14:26:59 +0000
> Subject: [PATCH] Make Warray-bounds alias to Warray-bounds= [PR107787]
>
> According to documentation the -Werror= option makes the specified warning
> into an error and also automatically implies this option. Then it seems that
> the behavior of the compiler when specifying -Werror=array-bounds=X should be
> the same as specifying "-Werror=array-bounds -Warray-bounds=X", so we expect to
> receive array-bounds pass triggers and they must be processed as errors.
> In practice, we observe that the array-bounds pass is indeed called, but
> its responses are processed as warnings, not errors.
> As I understand, this happens because Warray-bounds and Warray-bounds= are
> declared as 2 different options in common.opt, so when
> diagnostic_classify_diagnostic() is called, DK_ERROR is set for
> the Warray-bounds= option, but in diagnostic_report_diagnostic() through
> warning_at() passes opt_index of Warray-bounds, so information about
> DK_ERROR is lost. Fixed by using Alias() in declaration of
> Warray-bounds (similarly as in Wattribute-alias etc.)

OK if this passed bootstrap & regtest.

Thanks,
Richard.

> PR driver/107787
>
> Co-authored-by: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
>
> gcc/ChangeLog:
>
> * common.opt (Warray-bounds): Turn into alias to
> -Warray-bounds=1.
> * builtins.cc (warn_array_bounds): Use OPT_Warray_bounds_
> instead of OPT_Warray_bounds.
> * diagnostic-spec.cc: Likewise.
> * gimple-array-bounds.cc: Likewise.
> * gimple-ssa-warn-restrict.cc: Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/Warray-bounds-34.c: Correct the regular
> expression for -Warray-bounds=.
> * gcc.dg/Warray-bounds-43.c: Likewise.
> * gcc.dg/pr107787.c: New test.
>
> gcc/c-family/ChangeLog:
>
> * c-common.cc (warn_array_bounds): Use OPT_Warray_bounds_
> instead of OPT_Warray_bounds.
> ---
>  gcc/builtins.cc                         |  6 ++--
>  gcc/c-family/c-common.cc                |  4 +--
>  gcc/common.opt                          |  3 +-
>  gcc/diagnostic-spec.cc                  |  1 -
>  gcc/gimple-array-bounds.cc              | 38 ++++++++++++-------------
>  gcc/gimple-ssa-warn-restrict.cc         |  2 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-34.c |  2 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-43.c |  6 ++--
>  gcc/testsuite/gcc.dg/pr107787.c         | 13 +++++++++
>  9 files changed, 43 insertions(+), 32 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr107787.c
>
> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> index 4dc1ca672b2..02c4fefa86f 100644
> --- a/gcc/builtins.cc
> +++ b/gcc/builtins.cc
> @@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
>      {
>        /* Suppress multiple warnings for propagated constant strings.  */
>        if (only_value != 2
> -  && !warning_suppressed_p (arg, OPT_Warray_bounds)
> -  && warning_at (loc, OPT_Warray_bounds,
> +  && !warning_suppressed_p (arg, OPT_Warray_bounds_)
> +  && warning_at (loc, OPT_Warray_bounds_,
>   "offset %qwi outside bounds of constant string",
>   eltoff))
>   {
>    if (decl)
>      inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
> -  suppress_warning (arg, OPT_Warray_bounds);
> +  suppress_warning (arg, OPT_Warray_bounds_);
>   }
>        return NULL_TREE;
>      }
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index 6f1f21bc4c1..b0da6886ccf 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
>       definition thereof.  */
>    if (TREE_CODE (v) == ARRAY_REF
>        || TREE_CODE (v) == COMPONENT_REF)
> -    warning (OPT_Warray_bounds,
> +    warning (OPT_Warray_bounds_,
>       "index %E denotes an offset "
>       "greater than size of %qT",
>       t, TREE_TYPE (TREE_OPERAND (expr, 0)));
> @@ -8534,7 +8534,7 @@ convert_vector_to_array_for_subscript (location_t loc,
>        if (TREE_CODE (index) == INTEGER_CST)
>          if (!tree_fits_uhwi_p (index)
>      || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
> -          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
> +          warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
>
>        /* We are building an ARRAY_REF so mark the vector as addressable
>           to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 26e9d1cc4e7..f91b631f257 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -539,8 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
>  Warn if a loop with constant number of iterations triggers undefined behavior.
>
>  Warray-bounds
> -Common Var(warn_array_bounds) Warning
> -Warn if an array is accessed out of bounds.
> +Common Alias(Warray-bounds=, 1, 0) Warning
>
>  Warray-bounds=
>  Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning IntegerRange(0, 2)
> diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
> index aece89619e7..7a03fc493e6 100644
> --- a/gcc/diagnostic-spec.cc
> +++ b/gcc/diagnostic-spec.cc
> @@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
>        break;
>
>        /* Access warning group.  */
> -    case OPT_Warray_bounds:
>      case OPT_Warray_bounds_:
>      case OPT_Wformat_overflow_:
>      case OPT_Wformat_truncation_:
> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
> index fbf448e045d..7af85b86f75 100644
> --- a/gcc/gimple-array-bounds.cc
> +++ b/gcc/gimple-array-bounds.cc
> @@ -182,7 +182,7 @@ bool
>  array_bounds_checker::check_array_ref (location_t location, tree ref,
>         gimple *stmt, bool ignore_off_by_one)
>  {
> -  if (warning_suppressed_p (ref, OPT_Warray_bounds))
> +  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
>      /* Return true to have the caller prevent warnings for enclosing
>         refs.  */
>      return true;
> @@ -287,7 +287,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>
>    /* Empty array.  */
>    if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
> -    warned = warning_at (location, OPT_Warray_bounds,
> +    warned = warning_at (location, OPT_Warray_bounds_,
>   "array subscript %E is outside array bounds of %qT",
>   low_sub, artype);
>
> @@ -313,7 +313,7 @@ array_bounds_checker::check_array_ref (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,
> + warned = warning_at (location, OPT_Warray_bounds_,
>       "array subscript [%E, %E] is outside "
>       "array bounds of %qT",
>       low_sub, up_sub, artype);
> @@ -323,12 +323,12 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>     && (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,
> +    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,
> +    warned = warning_at (location, OPT_Warray_bounds_,
>   "array subscript %E is below array bounds of %qT",
>   low_sub, artype);
>
> @@ -353,7 +353,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
>        /* 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_Warray_bounds_);
>
>        if (decl)
>   ref = decl;
> @@ -393,7 +393,7 @@ bool
>  array_bounds_checker::check_mem_ref (location_t location, tree ref,
>       bool ignore_off_by_one)
>  {
> -  if (warning_suppressed_p (ref, OPT_Warray_bounds))
> +  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
>      return false;
>
>    /* The statement used to allocate the array or null.  */
> @@ -493,12 +493,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>    if (lboob)
>      {
>        if (offrange[0] == offrange[1])
> - warned = warning_at (location, OPT_Warray_bounds,
> + warned = warning_at (location, OPT_Warray_bounds_,
>       "array subscript %wi is outside array bounds "
>       "of %qT",
>       offrange[0].to_shwi (), reftype);
>        else
> - warned = warning_at (location, OPT_Warray_bounds,
> + warned = warning_at (location, OPT_Warray_bounds_,
>       "array subscript [%wi, %wi] is outside "
>       "array bounds of %qT",
>       offrange[0].to_shwi (),
> @@ -513,7 +513,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>   backtype = build_array_type_nelts (unsigned_char_type_node,
>     aref.sizrng[1].to_uhwi ());
>
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>     "array subscript %<%T[%wi]%> is partly "
>     "outside array bounds of %qT",
>     axstype, offrange[0].to_shwi (), backtype);
> @@ -523,7 +523,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>      {
>        /* TODO: Determine the access from the statement and use it.  */
>        aref.inform_access (access_none);
> -      suppress_warning (ref, OPT_Warray_bounds);
> +      suppress_warning (ref, OPT_Warray_bounds_);
>        return true;
>      }
>
> @@ -536,11 +536,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
>      {
>        HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
>
> -      if (warning_at (location, OPT_Warray_bounds,
> +      if (warning_at (location, OPT_Warray_bounds_,
>        "intermediate array offset %wi is outside array bounds "
>        "of %qT", tmpidx, reftype))
>   {
> -  suppress_warning (ref, OPT_Warray_bounds);
> +  suppress_warning (ref, OPT_Warray_bounds_);
>    return true;
>   }
>      }
> @@ -572,7 +572,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>   warned = check_mem_ref (location, t, ignore_off_by_one);
>
>        if (warned)
> - suppress_warning (t, OPT_Warray_bounds);
> + suppress_warning (t, OPT_Warray_bounds_);
>
>        t = TREE_OPERAND (t, 0);
>      }
> @@ -580,7 +580,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>
>    if (TREE_CODE (t) != MEM_REF
>        || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
> -      || warning_suppressed_p (t, OPT_Warray_bounds))
> +      || warning_suppressed_p (t, OPT_Warray_bounds_))
>      return;
>
>    tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
> @@ -615,7 +615,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>    dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
>    fprintf (dump_file, "\n");
>   }
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>     "array subscript %wi is below "
>     "array bounds of %qT",
>     idx.to_shwi (), TREE_TYPE (tem));
> @@ -629,7 +629,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>    dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
>    fprintf (dump_file, "\n");
>   }
> -      warned = warning_at (location, OPT_Warray_bounds,
> +      warned = warning_at (location, OPT_Warray_bounds_,
>     "array subscript %wu is above "
>     "array bounds of %qT",
>     idx.to_uhwi (), TREE_TYPE (tem));
> @@ -640,7 +640,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
>        if (DECL_P (t))
>   inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
>
> -      suppress_warning (t, OPT_Warray_bounds);
> +      suppress_warning (t, OPT_Warray_bounds_);
>      }
>  }
>
> @@ -740,7 +740,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
>    /* Propagate the no-warning bit to the outer statement to avoid also
>       issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
>    if (warned)
> -    suppress_warning (wi->stmt, OPT_Warray_bounds);
> +    suppress_warning (wi->stmt, OPT_Warray_bounds_);
>
>    return NULL_TREE;
>  }
> diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
> index 832456ba6fc..107ba278798 100644
> --- a/gcc/gimple-ssa-warn-restrict.cc
> +++ b/gcc/gimple-ssa-warn-restrict.cc
> @@ -1734,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
>    if (!oobref)
>      return no_warning;
>
> -  const opt_code opt = OPT_Warray_bounds;
> +  const opt_code opt = OPT_Warray_bounds_;
>    /* Return true without issuing a warning.  */
>    if (!do_warn)
>      return opt;
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-34.c b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
> index cea7c4b32a2..1b2a098ad86 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-34.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
> @@ -7,7 +7,7 @@ int x;
>
>  inline void foo (int i)
>  {
> -  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds]" } */
> +  a[i + 1] = 123;   /* { dg-warning "\\\[-Warray-bounds" } */
>  }
>
>  int bar (void)
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
> index 0f521a7250d..43a83315787 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
> @@ -19,7 +19,7 @@ NOIPA int g2 (int i)
>
>    sink (p0, p1, p2);
>
> -  return p2[8];     // { dg-warning "\\\[-Warray-bounds]" }
> +  return p2[8];     // { dg-warning "\\\[-Warray-bounds" }
>  }
>
>  NOIPA int g3 (int i)
> @@ -33,7 +33,7 @@ NOIPA int g3 (int i)
>
>    sink (p0, p1, p2, p3);
>
> -  return p3[7];     // { dg-warning "\\\[-Warray-bounds]" }
> +  return p3[7];     // { dg-warning "\\\[-Warray-bounds" }
>  }
>
>  NOIPA int g4 (int i)
> @@ -48,7 +48,7 @@ NOIPA int g4 (int i)
>
>    sink (p0, p1, p2, p3, p4);
>
> -  return p4[6];     // { dg-warning "\\\[-Warray-bounds]" }
> +  return p4[6];     // { dg-warning "\\\[-Warray-bounds" }
>  }
>
>  NOIPA int g5 (int i)
> diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
> new file mode 100644
> index 00000000000..922dbff8b2a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr107787.c
> @@ -0,0 +1,13 @@
> +/* PR driver/107787 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Werror=array-bounds=1" } */
> +/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
> +
> +int a[10];     /* { dg-note "while referencing" } */
> +
> +int* f(void) {
> +
> +    a[-1] = 0; /* { dg-error "is below array bounds" } */
> +
> +    return a;
> +}
> --
> 2.25.1
>
  

Patch

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4dc1ca672b2..02c4fefa86f 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -696,14 +696,14 @@  c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
     {
       /* Suppress multiple warnings for propagated constant strings.  */
       if (only_value != 2
-	  && !warning_suppressed_p (arg, OPT_Warray_bounds)
-	  && warning_at (loc, OPT_Warray_bounds,
+	  && !warning_suppressed_p (arg, OPT_Warray_bounds_)
+	  && warning_at (loc, OPT_Warray_bounds_,
 			 "offset %qwi outside bounds of constant string",
 			 eltoff))
 	{
 	  if (decl)
 	    inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
-	  suppress_warning (arg, OPT_Warray_bounds);
+	  suppress_warning (arg, OPT_Warray_bounds_);
 	}
       return NULL_TREE;
     }
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 6f1f21bc4c1..b0da6886ccf 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -6811,7 +6811,7 @@  fold_offsetof (tree expr, tree type, enum tree_code ctx)
 		     definition thereof.  */
 		  if (TREE_CODE (v) == ARRAY_REF
 		      || TREE_CODE (v) == COMPONENT_REF)
-		    warning (OPT_Warray_bounds,
+		    warning (OPT_Warray_bounds_,
 			     "index %E denotes an offset "
 			     "greater than size of %qT",
 			     t, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -8534,7 +8534,7 @@  convert_vector_to_array_for_subscript (location_t loc,
       if (TREE_CODE (index) == INTEGER_CST)
         if (!tree_fits_uhwi_p (index)
 	    || maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
-          warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+          warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
 
       /* We are building an ARRAY_REF so mark the vector as addressable
          to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
diff --git a/gcc/common.opt b/gcc/common.opt
index 26e9d1cc4e7..e475d6e56eb 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -539,7 +539,7 @@  Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
 Warn if a loop with constant number of iterations triggers undefined behavior.
 
 Warray-bounds
-Common Var(warn_array_bounds) Warning
+Common Alias(Warray-bounds=, 1, 0) Warning
 Warn if an array is accessed out of bounds.
 
 Warray-bounds=
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index aece89619e7..7a03fc493e6 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -79,7 +79,6 @@  nowarn_spec_t::nowarn_spec_t (opt_code opt)
       break;
 
       /* Access warning group.  */
-    case OPT_Warray_bounds:
     case OPT_Warray_bounds_:
     case OPT_Wformat_overflow_:
     case OPT_Wformat_truncation_:
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index fbf448e045d..7af85b86f75 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -182,7 +182,7 @@  bool
 array_bounds_checker::check_array_ref (location_t location, tree ref,
 				       gimple *stmt, bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     /* Return true to have the caller prevent warnings for enclosing
        refs.  */
     return true;
@@ -287,7 +287,7 @@  array_bounds_checker::check_array_ref (location_t location, tree ref,
 
   /* Empty array.  */
   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
-    warned = warning_at (location, OPT_Warray_bounds,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is outside array bounds of %qT",
 			 low_sub, artype);
 
@@ -313,7 +313,7 @@  array_bounds_checker::check_array_ref (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,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%E, %E] is outside "
 			     "array bounds of %qT",
 			     low_sub, up_sub, artype);
@@ -323,12 +323,12 @@  array_bounds_checker::check_array_ref (location_t location, tree ref,
 	   && (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,
+    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,
+    warned = warning_at (location, OPT_Warray_bounds_,
 			 "array subscript %E is below array bounds of %qT",
 			 low_sub, artype);
 
@@ -353,7 +353,7 @@  array_bounds_checker::check_array_ref (location_t location, tree ref,
       /* 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_Warray_bounds_);
 
       if (decl)
 	ref = decl;
@@ -393,7 +393,7 @@  bool
 array_bounds_checker::check_mem_ref (location_t location, tree ref,
 				     bool ignore_off_by_one)
 {
-  if (warning_suppressed_p (ref, OPT_Warray_bounds))
+  if (warning_suppressed_p (ref, OPT_Warray_bounds_))
     return false;
 
   /* The statement used to allocate the array or null.  */
@@ -493,12 +493,12 @@  array_bounds_checker::check_mem_ref (location_t location, tree ref,
   if (lboob)
     {
       if (offrange[0] == offrange[1])
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript %wi is outside array bounds "
 			     "of %qT",
 			     offrange[0].to_shwi (), reftype);
       else
-	warned = warning_at (location, OPT_Warray_bounds,
+	warned = warning_at (location, OPT_Warray_bounds_,
 			     "array subscript [%wi, %wi] is outside "
 			     "array bounds of %qT",
 			     offrange[0].to_shwi (),
@@ -513,7 +513,7 @@  array_bounds_checker::check_mem_ref (location_t location, tree ref,
 	backtype = build_array_type_nelts (unsigned_char_type_node,
 					   aref.sizrng[1].to_uhwi ());
 
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %<%T[%wi]%> is partly "
 			   "outside array bounds of %qT",
 			   axstype, offrange[0].to_shwi (), backtype);
@@ -523,7 +523,7 @@  array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       /* TODO: Determine the access from the statement and use it.  */
       aref.inform_access (access_none);
-      suppress_warning (ref, OPT_Warray_bounds);
+      suppress_warning (ref, OPT_Warray_bounds_);
       return true;
     }
 
@@ -536,11 +536,11 @@  array_bounds_checker::check_mem_ref (location_t location, tree ref,
     {
       HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
 
-      if (warning_at (location, OPT_Warray_bounds,
+      if (warning_at (location, OPT_Warray_bounds_,
 		      "intermediate array offset %wi is outside array bounds "
 		      "of %qT", tmpidx, reftype))
 	{
-	  suppress_warning (ref, OPT_Warray_bounds);
+	  suppress_warning (ref, OPT_Warray_bounds_);
 	  return true;
 	}
     }
@@ -572,7 +572,7 @@  array_bounds_checker::check_addr_expr (location_t location, tree t,
 	warned = check_mem_ref (location, t, ignore_off_by_one);
 
       if (warned)
-	suppress_warning (t, OPT_Warray_bounds);
+	suppress_warning (t, OPT_Warray_bounds_);
 
       t = TREE_OPERAND (t, 0);
     }
@@ -580,7 +580,7 @@  array_bounds_checker::check_addr_expr (location_t location, tree t,
 
   if (TREE_CODE (t) != MEM_REF
       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
-      || warning_suppressed_p (t, OPT_Warray_bounds))
+      || warning_suppressed_p (t, OPT_Warray_bounds_))
     return;
 
   tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
@@ -615,7 +615,7 @@  array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wi is below "
 			   "array bounds of %qT",
 			   idx.to_shwi (), TREE_TYPE (tem));
@@ -629,7 +629,7 @@  array_bounds_checker::check_addr_expr (location_t location, tree t,
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
 	  fprintf (dump_file, "\n");
 	}
-      warned = warning_at (location, OPT_Warray_bounds,
+      warned = warning_at (location, OPT_Warray_bounds_,
 			   "array subscript %wu is above "
 			   "array bounds of %qT",
 			   idx.to_uhwi (), TREE_TYPE (tem));
@@ -640,7 +640,7 @@  array_bounds_checker::check_addr_expr (location_t location, tree t,
       if (DECL_P (t))
 	inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
 
-      suppress_warning (t, OPT_Warray_bounds);
+      suppress_warning (t, OPT_Warray_bounds_);
     }
 }
 
@@ -740,7 +740,7 @@  array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
   /* Propagate the no-warning bit to the outer statement to avoid also
      issuing -Wstringop-overflow/-overread for the out-of-bounds accesses.  */
   if (warned)
-    suppress_warning (wi->stmt, OPT_Warray_bounds);
+    suppress_warning (wi->stmt, OPT_Warray_bounds_);
 
   return NULL_TREE;
 }
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index 832456ba6fc..107ba278798 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -1734,7 +1734,7 @@  maybe_diag_access_bounds (gimple *call, tree func, int strict,
   if (!oobref)
     return no_warning;
 
-  const opt_code opt = OPT_Warray_bounds;
+  const opt_code opt = OPT_Warray_bounds_;
   /* Return true without issuing a warning.  */
   if (!do_warn)
     return opt;
diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
new file mode 100644
index 00000000000..79112691b63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107787.c
@@ -0,0 +1,13 @@ 
+/* PR driver/107787 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Werror=array-bounds=1" } */
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+int a[10];     /* { dg-note "while referencing" } */
+
+int* f(void) {
+
+    a[-1] = 0; /* { dg-error "is below array bounds" } */
+
+    return a;
+}