On Fri, Jun 27, 2025 at 06:49:12PM -0400, Jason Merrill wrote:
> On 6/27/25 5:58 PM, Jakub Jelinek wrote:
> > 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 using cp_save_expr and if needed, evaluating it before the
> > condition; for constant indexes this shouldn't change anything, and for
> > larger expressions in idx I think the patch should result in smaller
> > generated code, no need to duplicate all the evaluation in each of the
> > branches.
> 
> Evaluating idx before op0 seems to violate
> https://eel.is/c++draft/expr#cond-1
> 
> "The first expression is sequenced before the second or third expression
> ([intro.execution])."

Oops, yes.  That one could be still handled by turning the condition
into SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>.
But for C++17 there is also
"In a subscript expression E1[E2], E1 is sequenced before E2."
and I'm not sure how can that be handled.

So, kill the optimization unless idx is INTEGER_CST (am not sure
TREE_SIDE_EFFECTS is sufficient because it could be e.g. reading from some
VAR_DECL), and perhaps try to recover the optimization in GIMPLE?
Though, I think we don't gimplify ARRAY_REF into ARRAY_REF if the first
operand is not an array and don't create ARRAY_REFs for what has been
written as *(arr + idx).  On the other side, ARRAY_REF is beneficial
primary for the simple cases, so maybe if op1 and op2 are ADDR_EXPRs
of non-volatile VAR_DECLs or COMPONENT_REFs with VAR_DECL bases so
constant or constant offset from frame, E1 is sequenced before E2 won't
be really observable and we could use the 3 SAVE_EXPRs.

I think it has been added for
https://gcc.gnu.org/pipermail/gcc-patches/2001-April/thread.html#48160
but I'm sure GIMPLE in between FE and expansion changed things sufficiently
that it won't ICE anymore.

        Jakub

Reply via email to