The following code snippet: #include <stdio.h> int main(void) { const long ONE = 1L; long y = 0L; long x = ((long) (ONE || (y = 1L)) % 8L); printf("x = %ld, y = %ld\n", x, y); // with -O1/-O2/-O3 flag, gcc prints x = 1, y = 1 where clang prints x = 1, y = 0 } > $ /usr/gcc-trunk/bin/gcc -O2 -Wall -Wextra bug.c -o a.out > $ ./a.out > x = 1, y = 1 If the first operand of a logical-OR operation has a nonzero value, the second operand is not evaluated. Therefore (y = 1L) should not be evaluated. It should print y = 0 instead of y = 1. This bug appears in GCC-4.8, GCC-6.4.0, GCC-7.5.0, GCC-8.4.0, GCC-9.3.0, GCC-10.2.0 and GCC-11.0.0 20200501.
Works with -O0, already failed with -O1 in .original: long int x = y = 1;, 1; works with the C++ frontend so a frontend specific "misoptimization".
Actually it appears the wrong code is being introduced somewhere in fold_range_test (I didn't trace it further than that); the only front-end involvement is that the front end does folding as part of conversions at various points. Testing with old compilers suggests this appeared between 4.8.1 and 4.8.3 (quite possibly through some backported change perturbing the exact sequence of calls to folding functions rather than the actual underlying cause being introduced in whatever backport).
I have a patch.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:10231958fcfb13bc4847729eba21470c101b4a88 commit r11-2450-g10231958fcfb13bc4847729eba21470c101b4a88 Author: Richard Biener <rguenther@suse.de> Date: Fri Jul 31 08:41:56 2020 +0200 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.
Fixed on trunk sofar.
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:d3a0ef7a523fb4cdeabfbb9fab56bfcf8d21ffd5 commit r10-8745-gd3a0ef7a523fb4cdeabfbb9fab56bfcf8d21ffd5 Author: Richard Biener <rguenther@suse.de> Date: Fri Jul 31 08:41:56 2020 +0200 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. (cherry picked from commit 10231958fcfb13bc4847729eba21470c101b4a88)
The releases/gcc-9 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:505767905735a3c8f171c140108ee263f9fdcad6 commit r9-9093-g505767905735a3c8f171c140108ee263f9fdcad6 Author: Richard Biener <rguenther@suse.de> Date: Fri Jul 31 08:41:56 2020 +0200 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. (cherry picked from commit 10231958fcfb13bc4847729eba21470c101b4a88)
The releases/gcc-8 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:371ae12cf3b22795246a5707017f07257b5cbc97 commit r8-10803-g371ae12cf3b22795246a5707017f07257b5cbc97 Author: Richard Biener <rguenther@suse.de> Date: Fri Jul 31 08:41:56 2020 +0200 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. (cherry picked from commit 505767905735a3c8f171c140108ee263f9fdcad6)
Fixed.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:e217e7dbdc1040e7ee160796e9ca1ef12a0dd1cb commit r15-2136-ge217e7dbdc1040e7ee160796e9ca1ef12a0dd1cb Author: Sam James <sam@gentoo.org> Date: Thu Jul 18 10:00:17 2024 +0200 testsuite: Add dg-do run to more tests All of these are for wrong-code bugs. Confirmed to be used before but with no execution. 2024-07-18 Sam James <sam@gentoo.org> PR c++/53288 PR c++/57437 PR c/65345 PR libstdc++/88101 PR tree-optimization/96369 PR tree-optimization/102124 PR tree-optimization/108692 * c-c++-common/pr96369.c: Add dg-do run directive. * gcc.dg/torture/pr102124.c: Ditto. * gcc.dg/pr108692.c: Ditto. * gcc.dg/atomic/pr65345-4.c: Ditto. * g++.dg/cpp0x/lambda/lambda-return1.C: Ditto. * g++.dg/init/lifetime4.C: Ditto. * g++.dg/torture/builtin-clear-padding-1.C: Ditto. * g++.dg/torture/builtin-clear-padding-2.C: Ditto. * g++.dg/torture/builtin-clear-padding-3.C: Ditto. * g++.dg/torture/builtin-clear-padding-4.C: Ditto. * g++.dg/torture/builtin-clear-padding-5.C: Ditto.