Hi, On Tue Mar 25, 2025 at 8:33 PM CET, Simon Martin wrote: > 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. For information I have just backported this to 14 (r14-11602) and 13 (r13-9523).
Simon