diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2017-01-24 09:50:33 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2017-01-24 09:50:33 +0000 |
commit | 4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a (patch) | |
tree | 614d8e6c368054981229a5d1d26c4713f237c1fa | |
parent | cf8e20bfd8c8fd29869544452e31557a15d3e388 (diff) | |
download | gcc-4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a.zip gcc-4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a.tar.gz gcc-4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a.tar.bz2 |
re PR middle-end/79123 (incorrect -Walloca-larger-than: alloca may be too large due to conversion from long int to long unsigned int)
PR middle-end/79123
* gimple-ssa-warn-alloca.c (alloca_call_type): Make sure
casts from signed to unsigned really don't have a range.
From-SVN: r244859
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-ssa-warn-alloca.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Walloca-13.c | 11 |
3 files changed, 40 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96def33..e66fb83 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-01-24 Aldy Hernandez <aldyh@redhat.com> + + PR middle-end/79123 + * gimple-ssa-warn-alloca.c (alloca_call_type): Make sure + casts from signed to unsigned really don't have a range. + 2017-01-24 Markus Trippelsdorf <markus@trippelsdorf.de> * gimple-ssa-sprintf.c (format_floating): Change MPFR_RNDx to diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c index a27eea1..d553a34 100644 --- a/gcc/gimple-ssa-warn-alloca.c +++ b/gcc/gimple-ssa-warn-alloca.c @@ -272,6 +272,7 @@ static struct alloca_type_and_limit alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type) { gcc_assert (gimple_alloca_call_p (stmt)); + bool tentative_cast_from_signed = false; tree len = gimple_call_arg (stmt, 0); tree len_casted = NULL; wide_int min, max; @@ -352,8 +353,26 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type) // with this heuristic. Hopefully, this VR_ANTI_RANGE // nonsense will go away, and we won't have to catch the // sign conversion problems with this crap. + // + // This is here to catch things like: + // void foo(signed int n) { + // if (n < 100) + // alloca(n); + // ... + // } if (cast_from_signed_p (len, invalid_casted_type)) - return alloca_type_and_limit (ALLOCA_CAST_FROM_SIGNED); + { + // Unfortunately this also triggers: + // + // __SIZE_TYPE__ n = (__SIZE_TYPE__)blah; + // if (n < 100) + // alloca(n); + // + // ...which is clearly bounded. So, double check that + // the paths leading up to the size definitely don't + // have a bound. + tentative_cast_from_signed = true; + } } // No easily determined range and try other things. } @@ -371,10 +390,12 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type) ret = alloca_call_type_by_arg (len, len_casted, EDGE_PRED (bb, ix), max_size); if (ret.type != ALLOCA_OK) - return ret; + break; } } + if (tentative_cast_from_signed && ret.type != ALLOCA_OK) + return alloca_type_and_limit (ALLOCA_CAST_FROM_SIGNED); return ret; } diff --git a/gcc/testsuite/gcc.dg/Walloca-13.c b/gcc/testsuite/gcc.dg/Walloca-13.c new file mode 100644 index 0000000..f9bdcef --- /dev/null +++ b/gcc/testsuite/gcc.dg/Walloca-13.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Walloca-larger-than=100 -O2" } */ + +void f (void*); + +void g (int *p, int *q) +{ + __SIZE_TYPE__ n = (__SIZE_TYPE__)(p - q); + if (n < 100) + f (__builtin_alloca (n)); +} |