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

--- Comment #10 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Jakub Jelinek
<ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3

commit r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Sep 10 18:32:58 2024 +0200

    c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449]

    The following testcase is miscompiled, because
    get_member_function_from_ptrfunc
    emits something like
    (((FUNCTION.__pfn & 1) != 0)
     ? ptr + FUNCTION.__delta + FUNCTION.__pfn - 1
     : FUNCTION.__pfn) (ptr + FUNCTION.__delta, ...)
    or so, so FUNCTION tree is used there 5 times.  There is
    if (TREE_SIDE_EFFECTS (function)) function = save_expr (function);
    but in this case function doesn't have side-effects, just nested
ARRAY_REFs.
    Now, if all the FUNCTION trees would be shared, it would work fine,
    FUNCTION is evaluated in the first operand of COND_EXPR; but unfortunately
    that isn't the case, both the BIT_AND_EXPR shortening and conversion to
    bool done for build_conditional_expr actually unshare_expr that first
    expression, but none of the other 4 are unshared.  With -fsanitize=bounds,
    .UBSAN_BOUNDS calls are added to the ARRAY_REFs and use save_expr to avoid
    evaluating the argument multiple times, but because that FUNCTION tree is
    first used in the second argument of COND_EXPR (i.e. conditionally), the
    SAVE_EXPR initialization is done just there and then the third argument
    of COND_EXPR just uses the uninitialized temporary and so does the first
    argument computation as well.

    The following patch fixes that by doing save_expr even if
!TREE_SIDE_EFFECTS,
    but to avoid doing that too often only if !nonvirtual and if the expression
    isn't a simple decl.

    2024-09-10  Jakub Jelinek  <ja...@redhat.com>

            PR c++/116449
            * typeck.cc (get_member_function_from_ptrfunc): Use save_expr
            on instance_ptr and function even if it doesn't have side-effects,
            as long as it isn't a decl.

            * g++.dg/ubsan/pr116449.C: New test.

    (cherry picked from commit 0008050b9d6046ba4e811a03b406fb5d98707cae)

Reply via email to