]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Fix up cp_build_array_ref COND_EXPR handling [PR120471]
authorJakub Jelinek <jakub@redhat.com>
Tue, 1 Jul 2025 13:28:10 +0000 (15:28 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 3 Jul 2025 07:17:45 +0000 (09:17 +0200)
commitd21bfd170f939625abee3e230a6d41d7e1529ed3
tree6f061e38021403336d48abb74fb5280b0eb92fd2
parent72b828227f8faf8f0a85735a5c27545378cf20c5
c++: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

The following testcase is miscompiled since the introduction of UBSan,
cp_build_array_ref COND_EXPR handling replaces
(cond ? a : b)[idx] with cond ? a[idx] : b[idx], but if there are
SAVE_EXPRs inside of idx, they will be evaluated just in one of the
branches and the other uses uninitialized temporaries.

Fixed by keeping doing what it did if idx doesn't have side effects
and is invariant.  Otherwise if op1/op2 are ARRAY_TYPE arrays with
invariant addresses or pointers with invariant values, use
SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as a new condition
and SAVE_EXPR <idx> instead of idx for the recursive calls.
Otherwise punt, but if op1/op2 are ARRAY_TYPE, furthermore call
cp_default_conversion on array, so that COND_EXPR with ARRAY_TYPE doesn't
survive in the IL until expansion.

2025-07-01  Jakub Jelinek  <jakub@redhat.com>

PR c++/120471
gcc/cp/
* typeck.cc (cp_build_array_ref) <case COND_EXPR>: If idx is not
INTEGER_CST, don't optimize the case (but cp_default_conversion on
array early if it has ARRAY_TYPE) or use
SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers.  Formatting fixes.
gcc/testsuite/
* g++.dg/ubsan/pr120471.C: New test.
* g++.dg/parse/pr120471.C: New test.

(cherry picked from commit 988e87b66882875b14a6cab11c17516863c74a63)
gcc/cp/typeck.cc
gcc/testsuite/g++.dg/parse/pr120471.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ubsan/pr120471.C [new file with mode: 0644]