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

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

https://gcc.gnu.org/g:413985b632afb07032d3b32d992029fced187814

commit r15-7014-g413985b632afb07032d3b32d992029fced187814
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Jan 18 09:14:27 2025 +0100

    c++: Fix up find_array_ctor_elt RAW_DATA_CST handling [PR118534]

    This is the third bug discovered today with the
    https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673945.html
    hack but then turned into proper testcases where embed-24.C FAILed
    since introduction of optimized #embed support and the others when
    optimizing large C++ initializers using RAW_DATA_CST.

    find_array_ctor_elt already has RAW_DATA_CST support, but on the
    following testcases it misses one case I've missed.
    The CONSTRUCTORs in question went through the braced_list_to_string
    optimization which can turn INTEGER_CST RAW_DATA_CST INTEGER_CST
    into just larger RAW_DATA_CST covering even those 2 bytes around it
    (if they appear there in the underlying RAW_DATA_OWNER).
    With this optimization, RAW_DATA_CST can be the last CONSTRUCTOR_ELTS
    elt in a CONSTRUCTOR, either the sole one or say preceeded by some
    unrelated other elements.  Now, if RAW_DATA_CST is the only one or
    if there are no RAW_DATA_CSTs earlier in CONSTRUCTOR_ELTS, we can
    trigger a bug in find_array_ctor_elt.
    It has a smart optimization for the very common case where
    CONSTRUCTOR_ELTS have indexes and index of the last elt is equal
    to CONSTRUCTOR_NELTS (ary) - 1, then obviously we know there are
    no RAW_DATA_CSTs before it and the indexes just go from 0 to nelts-1,
    so when we care about any of those earlier indexes, we can just return i;
    and not worry about anything.
    Except it uses if (i < end) return i; rather than if (i < end - 1) return
i;
    For the latter cases, i.e. anything before the last elt, we know there
    are no surprises and return i; is right.  But for the if (i == end - 1)
    case, return i; is only correct if the last elt is not RAW_DATA_CST, if it
    is RAW_DATA_CST, we still need to split it, which is handled by the code
    later in the function.  So, for that we need begin = end - 1, so that the
    binary search will just care about that last element.

    2025-01-18  Jakub Jelinek  <ja...@redhat.com>

            PR c++/118534
            * constexpr.cc (find_array_ctor_elt): Don't return i early if
            i == end - 1 and the last elt's value is RAW_DATA_CST.

            * g++.dg/cpp/embed-24.C: New test.
            * g++.dg/cpp1y/pr118534.C: New test.

Reply via email to