tree-vrp.c (check_array_ref): Emit more warnings for warn_array_bounds >= 2.
authorMartin Uecker <uecker@eecs.berkeley.edu>
Wed, 14 Jan 2015 06:50:19 +0000 (22:50 -0800)
committerJeff Law <law@gcc.gnu.org>
Wed, 14 Jan 2015 06:50:19 +0000 (23:50 -0700)
* tree-vrp.c (check_array_ref): Emit more warnings
for warn_array_bounds >= 2.
* common.opt: New option -Warray-bounds=.
* doc/invoke.texi: Document -Warray-bounds=.

* c.opt: New option -Warray-bounds=.

* gcc.dg/Warray-bounds-11.c: New test-case.

From-SVN: r219577

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/common.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Warray-bounds-11.c [new file with mode: 0644]
gcc/tree-vrp.c

index eef9de94f2eea2f72570206bd30ace0fc69a4320..dd6ad6bd78e9e774cffcd245cf778cf869ea1b10 100644 (file)
@@ -1,3 +1,10 @@
+2015-01-13  Martin Uecker <uecker@eecs.berkeley.edu>
+
+       * tree-vrp.c (check_array_ref): Emit more warnings
+       for warn_array_bounds >= 2.
+       * common.opt: New option -Warray-bounds=.
+       * doc/invoke.texi: Document -Warray-bounds=.
+
 2015-01-14  Chung-Ju Wu  <jasonwucj@gmail.com>
 
        * config/nds32/nds32.opt (mforce-fp-as-gp): Remove.
index afc23db0d9bfb80fad2c2e678f9c49656de5bed8..1efb75ac13cb747007a32635f05cb27352f767c1 100644 (file)
@@ -1,3 +1,7 @@
+2015-01-13  Martin Uecker <uecker@eecs.berkeley.edu>
+
+       * c.opt: New option -Warray-bounds=.
+
 2015-01-09  Michael Collison  <michael.collison@linaro.org>
 
        * array-notation-common.c: Include hash-set.h, machmode.h,
index 064c69e5a1d920c2d39d35da5ed4da7331239a75..e61fc567c9e5c81b795e13a3580290f82dc158da 100644 (file)
@@ -279,6 +279,10 @@ Warray-bounds
 LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; in common.opt
 
+Warray-bounds=
+LangEnabledBy(C ObjC C++ ObjC++,Wall,1,0)
+; in common.opt
+
 Wassign-intercept
 ObjC ObjC++ Var(warn_assign_intercept) Warning
 Warn whenever an Objective-C assignment is being intercepted by the garbage collector
index e10426948352ffc11a9c483053332170487c2a97..3d1987559a881d42443989839a412fe051dc75dd 100644 (file)
@@ -529,6 +529,10 @@ Warray-bounds
 Common Var(warn_array_bounds) Warning
 Warn if an array is accessed out of bounds
 
+Warray-bounds=
+Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning
+Warn if an array is accessed out of bounds
+
 Wattributes
 Common Var(warn_attributes) Init(1) Warning
 Warn about inappropriate attribute usage
index d84e3b798edaaf24d0f4dfc471ebd90a0d565879..0a04d34d039f7ccd6ae6ca535ec5a607508c6703 100644 (file)
@@ -240,7 +240,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-fsyntax-only  -fmax-errors=@var{n}  -Wpedantic @gol
 -pedantic-errors @gol
 -w  -Wextra  -Wall  -Waddress  -Waggregate-return  @gol
--Waggressive-loop-optimizations -Warray-bounds @gol
+-Waggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
 -Wbool-compare @gol
 -Wno-attributes -Wno-builtin-macro-redefined @gol
 -Wc90-c99-compat -Wc99-c11-compat @gol
@@ -3389,7 +3389,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 @option{-Wall} turns on the following warning flags:
 
 @gccoptlist{-Waddress   @gol
--Warray-bounds @r{(only with} @option{-O2}@r{)}  @gol
+-Warray-bounds=1 @r{(only with} @option{-O2}@r{)}  @gol
 -Wc++11-compat  -Wc++14-compat@gol
 -Wchar-subscripts  @gol
 -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
@@ -4303,12 +4303,26 @@ Warn about overriding virtual functions that are not marked with the override
 keyword.
 
 @item -Warray-bounds
+@itemx -Warray-bounds=@var{n}
 @opindex Wno-array-bounds
 @opindex Warray-bounds
 This option is only active when @option{-ftree-vrp} is active
 (default for @option{-O2} and above). It warns about subscripts to arrays
 that are always out of bounds. This warning is enabled by @option{-Wall}.
 
+@table @gcctabopt
+@item -Warray-bounds=1
+This is the warning level of @option{-Warray-bounds} and is enabled
+by @option{-Wall}; higher levels are not, and must be explicitly requested.
+
+@item -Warray-bounds=2
+This warning level also warns about out of bounds access for
+arrays at the end of a struct and for arrays accessed through
+pointers. This warning level may give a larger number of
+false positives and is deactivated by default.
+@end table
+
+
 @item -Wbool-compare
 @opindex Wno-bool-compare
 @opindex Wbool-compare
index bc0cd1fa8abce82b934a2e776d6ddd541b56d3f5..c07074bae8a45cc4076da1c65e22a7072b7681c3 100644 (file)
@@ -1,3 +1,7 @@
+2015-01-13  Martin Uecker <uecker@eecs.berkeley.edu>
+
+       * gcc.dg/Warray-bounds-11.c: New test-case.
+
 2015-01-14  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
 
        * gcc.target/mips/octeon3-pipe-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-11.c b/gcc/testsuite/gcc.dg/Warray-bounds-11.c
new file mode 100644 (file)
index 0000000..2e68498
--- /dev/null
@@ -0,0 +1,96 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Warray-bounds=2" } */
+
+extern void* malloc(unsigned long x);
+
+int e[3];
+
+struct f { int f[3]; };
+
+extern void bar(int v[]);
+
+struct h {
+
+       int i;
+       int j[];
+};
+
+struct h0 {
+
+       int i;
+       int j[0];
+};
+
+struct h0b {
+
+       int i;
+       int j[0];
+       int k;
+};
+
+struct h1 {
+
+       int i;
+       int j[1];
+};
+
+struct h1b {
+
+       int i;
+       int j[1];
+       int k;
+};
+
+struct h3 {
+
+       int i;
+       int j[3];
+};
+
+struct h3b {
+
+       int i;
+       int j[3];
+       int k;
+};
+
+void foo(int (*a)[3])
+{
+       (*a)[4] = 1;    /* { dg-warning "subscript is above array bound" } */
+       a[0][0] = 1;    // ok
+       a[1][0] = 1;    // ok
+       a[1][4] = 1;    /* { dg-warning "subscript is above array bound" } */
+
+       int c[3] = { 0 };
+
+       c[4] = 1;       /* { dg-warning "subscript is above array bound" } */
+
+       e[4] = 1;       /* { dg-warning "subscript is above array bound" } */
+
+       struct f f;
+       f.f[4] = 1;     /* { dg-warning "subscript is above array bound" } */
+
+       struct h* h = malloc(sizeof(struct h) + 3 * sizeof(int));
+       struct h0* h0 = malloc(sizeof(struct h0) + 3 * sizeof(int));
+       struct h1* h1 = malloc(sizeof(struct h1) + 3 * sizeof(int));
+       struct h3* h3 = malloc(sizeof(struct h3));
+
+       h->j[4] = 1;    // flexible array member
+       h0->j[4] = 1;   // zero-sized array extension
+       h1->j[4] = 1;   /* { dg-warning "subscript is above array bound" } */
+       h3->j[4] = 1;   /* { dg-warning "subscript is above array bound" } */
+
+       struct h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int));
+       struct h1b* h1b = malloc(sizeof(struct h1b) + 3 * sizeof(int));
+       struct h3b* h3b = malloc(sizeof(struct h3b));
+//     h0b->j[4] = 1;
+       h1b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */
+       h3b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */
+
+       // make sure nothing gets optimized away
+       bar(*a);
+       bar(c);
+       bar(e);
+       bar(f.f);
+}
+
index f3e1d3d635165a781ef0cad1d818e68acb145018..2e0b158ab0db2be909ce7a5f213c65142128c1b0 100644 (file)
@@ -6498,7 +6498,8 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
   /* Accesses to trailing arrays via pointers may access storage
      beyond the types array bounds.  */
   base = get_base_address (ref);
-  if (base && TREE_CODE (base) == MEM_REF)
+  if ((warn_array_bounds < 2)
+      && base && TREE_CODE (base) == MEM_REF)
     {
       tree cref, next = NULL_TREE;