From de1b5c17fd1418f01f0a57d03023c21d888dc97c Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Tue, 13 Jan 2015 22:50:19 -0800 Subject: [PATCH] tree-vrp.c (check_array_ref): Emit more warnings for warn_array_bounds >= 2. * 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 | 7 ++ gcc/c-family/ChangeLog | 4 ++ gcc/c-family/c.opt | 4 ++ gcc/common.opt | 4 ++ gcc/doc/invoke.texi | 18 ++++- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/Warray-bounds-11.c | 96 +++++++++++++++++++++++++ gcc/tree-vrp.c | 3 +- 8 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-11.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eef9de94f2e..dd6ad6bd78e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-01-13 Martin Uecker + + * 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 * config/nds32/nds32.opt (mforce-fp-as-gp): Remove. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index afc23db0d9b..1efb75ac13c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2015-01-13 Martin Uecker + + * c.opt: New option -Warray-bounds=. + 2015-01-09 Michael Collison * array-notation-common.c: Include hash-set.h, machmode.h, diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 064c69e5a1d..e61fc567c9e 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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 diff --git a/gcc/common.opt b/gcc/common.opt index e1042694835..3d1987559a8 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d84e3b798ed..0a04d34d039 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc0cd1fa8ab..c07074bae8a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-01-13 Martin Uecker + + * gcc.dg/Warray-bounds-11.c: New test-case. + 2015-01-14 Naveen H.S * 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 index 00000000000..2e684987e8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-11.c @@ -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); +} + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f3e1d3d6351..2e0b158ab0d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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; -- 2.30.2