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

--- Comment #45 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:8c15a6cefa0d1f8ec12701af1f528f473c33ff6b

commit r15-7770-g8c15a6cefa0d1f8ec12701af1f528f473c33ff6b
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Mar 1 11:22:27 2025 +0100

    ggc: Avoid using ATTRIBUTE_MALLOC for allocations that need finalization
[PR117047]

    As analyzed by Andrew/David/Richi/Sam in the PR, the reason for the
    libgccjit ICE is that there are GC allocations with finalizers and we
    still mark ggc_internal_{,cleared_}alloc with ATTRIBUTE_MALLOC, which
    to the optimizers hints that nothing will actually read the state
    of the objects when they get out of lifetime.  The finalizer actually
    inspects those though.  What actually happens in the testcases is that on
      tree expr_size = TYPE_SIZE (expr->get_type ()->as_tree ());
    we see that expr->get_type () was allocated using something with malloc
    attribute but it doesn't escape and only the type size from it is queried,
    so there is no need to store other members of it.  Except that it does
escape
    in the GC internals.  Normal GC allocations are fine, they don't look at
the
    data in the allocated objects on "free", but the ones with finalizers
actually
    call a function on that object and expect the data to be in there.
    So that we don't lose ATTRIBUTE_MALLOC for the common case when no
    finalization is needed, the following patch uses the approach used e.g.
    for glibc error function which can sometimes be noreturn but at other
    times just return normally.
    If possible, it uses __attribute__((alias ("..."))) to add an alias
    to the function, where one is without ATTRIBUTE_MALLOC and one
    (with _no_dtor suffix) is with ATTRIBUTE_MALLOC (note, as this is
    C++ and I didn't want to hardcode particular mangling I used an
    extern "C" function with 2 aliases to it), and otherwise adds a wrapper
    (for the ggc-page/ggc-common case with noinline attribute if possible,
    for ggc-none that doesn't matter because ggc-none doesn't support
    finalizers).
    The *_no_dtor aliases/wrappers are then used in inline functions which
    pass unconditional NULL, 0 as the f/s pair.

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

            PR jit/117047
            * acinclude.m4 (gcc_CHECK_ATTRIBUTE_ALIAS): New.
            * configure.ac: Add gcc_CHECK_ATTRIBUTE_ALIAS.
            * ggc.h (ggc_internal_alloc): Remove ATTRIBUTE_MALLOC from
            overload with finalizer pointer.  Call ggc_internal_alloc_no_dtor
            in inline overload without finalizer pointer.
            (ggc_internal_alloc_no_dtor): Declare.
            (ggc_internal_cleared_alloc): Remove ATTRIBUTE_MALLOC from
            overload with finalizer pointer.  Call
            ggc_internal_cleared_alloc_no_dtor in inline overload without
            finalizer pointer.
            (ggc_internal_cleared_alloc_no_dtor): Declare.
            (ggc_alloc): Call ggc_internal_alloc_no_dtor if no finalization
            is needed.
            (ggc_alloc_no_dtor): Call ggc_internal_alloc_no_dtor.
            (ggc_cleared_alloc): Call ggc_internal_cleared_alloc_no_dtor if no
            finalization is needed.
            (ggc_vec_alloc): Call ggc_internal_alloc_no_dtor if no finalization
            is needed.
            (ggc_cleared_vec_alloc): Call ggc_internal_cleared_alloc_no_dtor if
no
            finalization is needed.
            * ggc-page.cc (ggc_internal_alloc): If HAVE_ATTRIBUTE_ALIAS, turn
            overload with finalizer into alias to ggc_internal_alloc_ and
            rename it to ...
            (ggc_internal_alloc_): ... this, make it extern "C".
            (ggc_internal_alloc_no_dtor): New alias if HAVE_ATTRIBUTE_ALIAS,
            otherwise new noinline wrapper.
            * ggc-common.cc (ggc_internal_cleared_alloc): If
HAVE_ATTRIBUTE_ALIAS,
            turn overload with finalizer into alias to ggc_internal_alloc_ and
            rename it to ...
            (ggc_internal_cleared_alloc_): ... this, make it extern "C".
            (ggc_internal_cleared_alloc_no_dtor): New alias if
            HAVE_ATTRIBUTE_ALIAS, otherwise new noinline wrapper.
            * ggc-none.cc (ggc_internal_alloc): If HAVE_ATTRIBUTE_ALIAS, turn
            overload with finalizer into alias to ggc_internal_alloc_ and
            rename it to ...
            (ggc_internal_alloc_): ... this, make it extern "C".
            (ggc_internal_alloc_no_dtor): New alias if HAVE_ATTRIBUTE_ALIAS,
            otherwise new wrapper.
            (ggc_internal_cleared_alloc): If HAVE_ATTRIBUTE_ALIAS, turn
overload
            with finalizer into alias to ggc_internal_alloc_ and rename it to
...
            (ggc_internal_cleared_alloc_): ... this, make it extern "C".
            (ggc_internal_cleared_alloc_no_dtor): New alias if
            HAVE_ATTRIBUTE_ALIAS, otherwise new wrapper.
            * genmatch.cc (ggc_internal_cleared_alloc, ggc_free): Formatting
fix.
            (ggc_internal_cleared_alloc_no_dtor): Define.
            * config.in: Regenerate.
            * configure: Regenerate.

Reply via email to