https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114525

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Simon Martin <simar...@gcc.gnu.org>:

https://gcc.gnu.org/g:35ce9afc84a63fb647a90cbecb2adf3e748178be

commit r15-8911-g35ce9afc84a63fb647a90cbecb2adf3e748178be
Author: Simon Martin <si...@nasilyan.com>
Date:   Tue Mar 25 20:11:19 2025 +0100

    c++: Properly fold <COND_EXPR>.*<COMPONENT> [PR114525]

    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.

            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/expr/cond18.C: New test.

Reply via email to