aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2017-01-24 09:50:33 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2017-01-24 09:50:33 +0000
commit4cd7b1a9e072d2bf4d47bd99ffe8ac482f35321a (patch)
tree614d8e6c368054981229a5d1d26c4713f237c1fa /gcc
parentcf8e20bfd8c8fd29869544452e31557a15d3e388 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-ssa-warn-alloca.c25
-rw-r--r--gcc/testsuite/gcc.dg/Walloca-13.c11
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));
+}