From: Marek Polacek Date: Wed, 26 Jul 2017 11:53:17 +0000 (+0000) Subject: re PR middle-end/70992 (Infinite recursion between fold_build2_stat_loc and fold_bina... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c3d3862950f5708af0db77c76b5db4db5e65740c;p=gcc.git re PR middle-end/70992 (Infinite recursion between fold_build2_stat_loc and fold_binary_loc w/ -fwrapv) PR middle-end/70992 * tree.c (build2_stat): Don't set TREE_CONSTANT on divisions by zero. * gcc.dg/overflow-warn-1.c: Adjust dg-error. * gcc.dg/overflow-warn-2.c: Likewise. * gcc.dg/overflow-warn-3.c: Likewise. * gcc.dg/overflow-warn-4.c: Likewise. * gcc.dg/torture/pr70992-2.c: New test. * gcc.dg/torture/pr70992.c: New test. From-SVN: r250566 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff746ffc621..fa34e4974c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-07-26 Marek Polacek + + PR middle-end/70992 + * tree.c (build2_stat): Don't set TREE_CONSTANT on divisions by zero. + 2017-07-26 Richard Biener * gimple-match-head.c (do_valueize): Return OP if valueize diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aaec07c0026..b311c6a504d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2017-07-26 Marek Polacek + + PR middle-end/70992 + * gcc.dg/overflow-warn-1.c: Adjust dg-error. + * gcc.dg/overflow-warn-2.c: Likewise. + * gcc.dg/overflow-warn-3.c: Likewise. + * gcc.dg/overflow-warn-4.c: Likewise. + * gcc.dg/torture/pr70992-2.c: New test. + * gcc.dg/torture/pr70992.c: New test. + 2017-07-26 Richard Biener * gcc/testsuite/gcc.dg/pr70920-2.c: Adjust for transform already diff --git a/gcc/testsuite/gcc.dg/overflow-warn-1.c b/gcc/testsuite/gcc.dg/overflow-warn-1.c index 8eb322579cf..a5cd5738636 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-1.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-1.c @@ -49,7 +49,7 @@ static int sc = INT_MAX + 1; /* { dg-warning "25:integer overflow in expression" void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git a/gcc/testsuite/gcc.dg/overflow-warn-2.c b/gcc/testsuite/gcc.dg/overflow-warn-2.c index f048d6dae2a..05ab104fa4a 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-2.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-2.c @@ -49,7 +49,7 @@ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git a/gcc/testsuite/gcc.dg/overflow-warn-3.c b/gcc/testsuite/gcc.dg/overflow-warn-3.c index 664011e401d..fd4a34f67e2 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-3.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-3.c @@ -55,7 +55,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git a/gcc/testsuite/gcc.dg/overflow-warn-4.c b/gcc/testsuite/gcc.dg/overflow-warn-4.c index 52677ce897a..018e3e1e4cd 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-4.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-4.c @@ -55,7 +55,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } /* { dg-error "overflow in constant expression" "constant" { target *-*-* } .-1 } */ /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git a/gcc/testsuite/gcc.dg/torture/pr70992-2.c b/gcc/testsuite/gcc.dg/torture/pr70992-2.c new file mode 100644 index 00000000000..c5d2c5f2683 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr70992-2.c @@ -0,0 +1,9 @@ +/* PR middle-end/70992 */ +/* { dg-do compile } */ + +unsigned int *od; +int +fn (void) +{ + return (0 % 0 + 1) * *od * 2; /* { dg-warning "division by zero" } */ +} diff --git a/gcc/testsuite/gcc.dg/torture/pr70992.c b/gcc/testsuite/gcc.dg/torture/pr70992.c new file mode 100644 index 00000000000..56728e09d1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr70992.c @@ -0,0 +1,41 @@ +/* PR middle-end/70992 */ +/* { dg-do compile } */ + +typedef unsigned int uint32_t; +typedef int int32_t; + +uint32_t +fn (uint32_t so) +{ + return (so + so) * (0x80000000 / 0 + 1); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn5 (uint32_t so) +{ + return (0x80000000 / 0 + 1) * (so + so); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn6 (uint32_t so) +{ + return (0x80000000 / 0 - 1) * (so + so); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn2 (uint32_t so) +{ + return (so + so) * (0x80000000 / 0 - 1); /* { dg-warning "division by zero" } */ +} + +int32_t +fn3 (int32_t so) +{ + return (so + so) * (0x80000000 / 0 + 1); /* { dg-warning "division by zero" } */ +} + +int32_t +fn4 (int32_t so) +{ + return (so + so) * (0x80000000 / 0 - 1); /* { dg-warning "division by zero" } */ +} diff --git a/gcc/tree.c b/gcc/tree.c index b7de2840ac6..48fb2ce0651 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4456,7 +4456,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) tree build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) { - bool constant, read_only, side_effects; + bool constant, read_only, side_effects, div_by_zero; tree t; gcc_assert (TREE_CODE_LENGTH (code) == 2); @@ -4489,6 +4489,23 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) read_only = 1; side_effects = TREE_SIDE_EFFECTS (t); + switch (code) + { + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case EXACT_DIV_EXPR: + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + case TRUNC_MOD_EXPR: + div_by_zero = integer_zerop (arg1); + break; + default: + div_by_zero = false; + } + PROCESS_ARG (0); PROCESS_ARG (1); @@ -4505,7 +4522,8 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) else { TREE_READONLY (t) = read_only; - TREE_CONSTANT (t) = constant; + /* Don't mark X / 0 as constant. */ + TREE_CONSTANT (t) = constant && !div_by_zero; TREE_THIS_VOLATILE (t) = (TREE_CODE_CLASS (code) == tcc_reference && arg0 && TREE_THIS_VOLATILE (arg0));