Hi,

On Tue Mar 25, 2025 at 6:52 PM CET, Jason Merrill wrote:
> On 3/25/25 1:50 PM, Marek Polacek wrote:
>> On Tue, Mar 25, 2025 at 05:18:23PM +0000, Simon Martin wrote:
>>> We've been miscompiling the following since r0-51314-gd6b4ea8592e338 (I
>>> did not go compile something that old, and identified this change via
>>> git blame, so might be wrong)
>>>
>>> === cut here ===
>>> struct Foo { int x; };
>>> Foo& get (Foo &v) { return v; }
>>> void bar () {
>>>    Foo v; v.x = 1;
>>>    (true ? get (v) : get (v)).*(&Foo::x) = 2;
>>>    // v.x still equals 1 here...
>>> }
>>> === cut here ===
>>>
>>> The problem lies in build_m_component_ref, that computes the address of
>>> the COND_EXPR using build_address to build the representation of
>>>    (true ? get (v) : get (v)).*(&Foo::x);
>>> and gets something like
>>>    &(true ? get (v) : get (v))  // #1
>>> instead of
>>>    (true ? &get (v) : &get (v)) // #2
>>> and the write does not go where want it to, hence the miscompile.
>>>
>>> This patch replaces the call to build_address by a call to
>>> cp_build_addr_expr, which gives #2, that is properly handled.
>>>
>>> Successfully tested on x86_64-pc-linux-gnu. OK for trunk? And for active
>>> branches after 2-3 weeks since it's a nasty one (albeit very old)?
>>>
>>>     PR c++/114525
>>>
>>> gcc/cp/ChangeLog:
>>>
>>>     * typeck2.cc (build_m_component_ref): Call cp_build_addr_expr
>>>     instead of build_address.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>>     * g++.dg/parse/pr114525.C: New test.
>> 
>> g++.dg/expr/cond18.C seems like a more appropriate place, but the
>> patch itself LGTM.
Good call out, thanks Marek.

I've merged the patch with the suggested test rename as
r15-8911-g35ce9afc84a63f.

I'll reply to this thread in 2-3 weeks when I've backported to 13 and
14.

Simon

Reply via email to