From 86e3947eea1619c83ac45c77ba4b3156d729c81f Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 15 May 2019 14:58:53 +0200 Subject: [PATCH] Check for overflow in tree-switch-conversion (PR middle-end/90478). 2019-05-15 Martin Liska PR middle-end/90478 * tree-switch-conversion.c (jump_table_cluster::can_be_handled): Check for overflow. 2019-05-15 Martin Liska PR middle-end/90478 * gcc.dg/tree-ssa/pr90478-2.c: New test. * gcc.dg/tree-ssa/pr90478.c: New test. From-SVN: r271210 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/tree-ssa/pr90478-2.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr90478.c | 18 ++++++++++++++++++ gcc/tree-switch-conversion.c | 6 +++++- 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr90478-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr90478.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8bb14cf131d..f05bd98f39a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-05-15 Martin Liska + + PR middle-end/90478 + * tree-switch-conversion.c (jump_table_cluster::can_be_handled): + Check for overflow. + 2019-05-15 Richard Biener * tree-into-ssa.c (pass_build_ssa::execute): Run diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b7d63ed8210..c91e601a946 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-05-15 Martin Liska + + PR middle-end/90478 + * gcc.dg/tree-ssa/pr90478-2.c: New test. + * gcc.dg/tree-ssa/pr90478.c: New test. + 2019-05-15 Richard Biener * gcc.dg/gimplefe-40.c: Amend. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr90478-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr90478-2.c new file mode 100644 index 00000000000..f0fc103a888 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr90478-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-Os --param jump-table-max-growth-ratio-for-size=2147483647" } */ + +long +foo (long x, long y) +{ + x = x & y; + switch (y) + { + case 63L: x >>= 0; break; + case 4032L: x >>= 6; break; + case 258048L: x >>= 12; break; + case 16515072L: x >>= 18; break; + default: __builtin_unreachable (); + } + return x; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr90478.c b/gcc/testsuite/gcc.dg/tree-ssa/pr90478.c new file mode 100644 index 00000000000..f19808d2941 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr90478.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +typedef struct { + long a; +} c; + +void e(); + +void d() { + c *b; + switch (b->a) + case 8: + case 2: + case 2057594037927936: + case 0: + case 4611686018427387904: + e(); +} diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index bedeb2fd865..5f8ed46f496 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1284,7 +1284,11 @@ jump_table_cluster::can_be_handled (const vec &clusters, comparison_count += sc->m_range_p ? 2 : 1; } - return 100 * range <= max_ratio * comparison_count; + unsigned HOST_WIDE_INT lhs = 100 * range; + if (lhs < range) + return false; + + return lhs <= max_ratio * comparison_count; } /* Return true if cluster starting at START and ending at END (inclusive) -- 2.30.2