This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ICE with -Walloca-larger-than=[>INT_MAX] (PR middle-end/79809)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 2 Mar 2017 13:32:23 +0100
- Subject: [PATCH] Fix ICE with -Walloca-larger-than=[>INT_MAX] (PR middle-end/79809)
- Authentication-results: sourceware.org; auth=none
As demonstrated by this test, we can crash on the assert in alloca_call_type:
gcc_assert (is_vla || warn_alloca_limit > 0);
when -Walloca-larger-than= receives an argument greater than INT_MAX. Even
though warn_vla_limit is marked as UInteger in c.opt, those are still
represented as ints; opt-functions.awk has
202 else if (flag_set_p("UInteger", flags))
203 return "int "
...
213 if (flag_set_p("UInteger", flags))
214 return "int "
So 4207115063 is converted to int which is some negative value.
It's probably too late to change opt-functions.awk now, so the following
is a badn aid fix.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2017-03-02 Marek Polacek <polacek@redhat.com>
PR middle-end/79809
* gimple-ssa-warn-alloca.c (pass_walloca::gate): Use HOST_WIDE_INT.
(alloca_call_type): Likewise.
* g++.dg/Walloca1.C: New test.
diff --git gcc/gimple-ssa-warn-alloca.c gcc/gimple-ssa-warn-alloca.c
index d553a34..dd41775 100644
--- gcc/gimple-ssa-warn-alloca.c
+++ gcc/gimple-ssa-warn-alloca.c
@@ -78,7 +78,8 @@ pass_walloca::gate (function *fun ATTRIBUTE_UNUSED)
if (first_time_p)
return warn_alloca != 0;
- return warn_alloca_limit > 0 || warn_vla_limit > 0;
+ return ((unsigned HOST_WIDE_INT) warn_alloca_limit > 0
+ || (unsigned HOST_WIDE_INT) warn_vla_limit > 0);
}
// Possible problematic uses of alloca.
@@ -278,8 +279,8 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
wide_int min, max;
struct alloca_type_and_limit ret = alloca_type_and_limit (ALLOCA_UNBOUNDED);
- gcc_assert (!is_vla || warn_vla_limit > 0);
- gcc_assert (is_vla || warn_alloca_limit > 0);
+ gcc_assert (!is_vla || (unsigned HOST_WIDE_INT) warn_vla_limit > 0);
+ gcc_assert (is_vla || (unsigned HOST_WIDE_INT) warn_alloca_limit > 0);
// Adjust warn_alloca_max_size for VLAs, by taking the underlying
// type into account.
diff --git gcc/testsuite/g++.dg/Walloca1.C gcc/testsuite/g++.dg/Walloca1.C
index e69de29..23b97e8 100644
--- gcc/testsuite/g++.dg/Walloca1.C
+++ gcc/testsuite/g++.dg/Walloca1.C
@@ -0,0 +1,6 @@
+/* PR middle-end/79809 */
+/* { dg-do compile } */
+/* { dg-options "-Walloca-larger-than=4207115063 -Wvla-larger-than=1233877270 -O2" } */
+
+int a;
+char *b = static_cast<char *>(__builtin_alloca (a)); // { dg-warning "argument to .alloca. may be too large" }
Marek