aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-07-31 08:41:56 +0200
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 13:20:21 -0300
commit11a630f20c766ffa91cfe323e02bb7a0e55e5cff (patch)
tree49eedb0ff616a266d6ec659419aef8c1c526654d /gcc
parent24893cb6c1b8c56863331b6532a5f601c6f6c910 (diff)
downloadgcc-11a630f20c766ffa91cfe323e02bb7a0e55e5cff.zip
gcc-11a630f20c766ffa91cfe323e02bb7a0e55e5cff.tar.gz
gcc-11a630f20c766ffa91cfe323e02bb7a0e55e5cff.tar.bz2
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 <rguenther@suse.de> 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fold-const.c7
-rw-r--r--gcc/testsuite/c-c++-common/pr96369.c12
2 files changed, 19 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 300d959..1324a19 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 0000000..8c468d9
--- /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;
+}