From: Aldy Hernandez Date: Tue, 24 Jan 2017 09:50:33 +0000 (+0000) Subject: re PR middle-end/79123 (incorrect -Walloca-larger-than: alloca may be too large due... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96def33bd56..e66fb836d68 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-01-24 Aldy Hernandez + + 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 * 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 a27eea1fb4c..d553a346bfe 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 00000000000..f9bdcefa9d3 --- /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)); +}