https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120471
--- Comment #15 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>: https://gcc.gnu.org/g:988e87b66882875b14a6cab11c17516863c74a63 commit r16-1893-g988e87b66882875b14a6cab11c17516863c74a63 Author: Jakub Jelinek <ja...@redhat.com> Date: Tue Jul 1 15:28:10 2025 +0200 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 <ja...@redhat.com> PR c++/120471 gcc/ * tree.h (address_invariant_p): New function. * tree.cc (address_invariant_p): New function. (tree_invariant_p_1): Use it for ADDR_EXPR handling. Formatting tweak. 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.