From 10231958fcfb13bc4847729eba21470c101b4a88 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 31 Jul 2020 08:41:56 +0200 Subject: [PATCH] middle-end/96369 - fix missed short-circuiting during range folding This makes the special case of constant evaluated LHS for a short-circuiting or/and explicit rather than doing range merging and eventually exposing a side-effect that shouldn't be evaluated. 2020-07-31 Richard Biener PR middle-end/96369 * fold-const.c (fold_range_test): Special-case constant LHS for short-circuiting operations. * c-c++-common/pr96369.c: New testcase. --- gcc/fold-const.c | 7 +++++++ gcc/testsuite/c-c++-common/pr96369.c | 12 ++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/pr96369.c diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 300d959278b..1324a194995 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5931,6 +5931,13 @@ fold_range_test (location_t loc, enum tree_code code, tree type, return 0; lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p); + /* If op0 is known true or false and this is a short-circuiting + operation we must not merge with op1 since that makes side-effects + unconditional. So special-case this. */ + if (!lhs + && ((code == TRUTH_ORIF_EXPR && in0_p) + || (code == TRUTH_ANDIF_EXPR && !in0_p))) + return op0; rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p); /* If this is an OR operation, invert both sides; we will invert diff --git a/gcc/testsuite/c-c++-common/pr96369.c b/gcc/testsuite/c-c++-common/pr96369.c new file mode 100644 index 00000000000..8c468d9fec2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr96369.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +int main() +{ + const long ONE = 1L; + long y = 0L; + long x = ((long) (ONE || (y = 1L)) % 8L); + if (y != 0) + __builtin_abort (); + return 0; +} -- 2.30.2