diff options
author | Richard Biener <rguenther@suse.de> | 2020-07-31 08:41:56 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-07-31 12:05:26 +0200 |
commit | 10231958fcfb13bc4847729eba21470c101b4a88 (patch) | |
tree | 638d05239bb3e8ccb0f2bee286029e9c58b31315 /gcc/fold-const.c | |
parent | bc2b1a232b1825b421a1aaa21a0865b2d1e4e08c (diff) | |
download | gcc-10231958fcfb13bc4847729eba21470c101b4a88.zip gcc-10231958fcfb13bc4847729eba21470c101b4a88.tar.gz gcc-10231958fcfb13bc4847729eba21470c101b4a88.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/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 7 |
1 files changed, 7 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 |