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

--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Nathaniel Shead <nsh...@gcc.gnu.org>:

https://gcc.gnu.org/g:9fcb9d39c36ae0c1b1681c68d314580ae0c820c4

commit r15-8687-g9fcb9d39c36ae0c1b1681c68d314580ae0c820c4
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Sat Mar 22 23:04:12 2025 +1100

    c++/modules: Fix explicit instantiations and gnu_inlines [PR119154]

    My change in r15-8012 for PR c++/119154 exposed a bug with explicit
    instantation declarations.  The change cleared DECL_INTERFACE_KNOWN for
    all vague-linkage entities, including explicit instantiations.  When we
    then perform lazy loading at EOF (due to processing deferred function
    bodies), expand_or_defer_fn ends up calling import_export_decl which
    will error because DECL_INTERFACE_KNOWN is still unset but no definition
    is available in the file, violating some assertions.

    It turns out that for function templates marked inline we would not
    respect an 'extern template' imported in general, either; this patch
    fixes both of these issues by always treating explicit instantiations as
    external, and so marking DECL_INTERFACE_KNOWN eagerly.

    For an explicit instantiation declaration we don't want to emit the body
    of the function as it must be emitted in a different TU anyway.  And for
    explicit instantiation definitions we similarly know that it will have
    been emitted in the interface TU we streamed it in from, so there's
    no need to emit it.

    The same error can happen with lazy-loaded gnu_inlines at EOF; in some
    cases they'll be marked DECL_COMDAT and pass through the vague_linkage_p
    check anyway.  This patch reworks the handling of gnu_inlines to ensure
    that both DECL_INTERFACE_KNOWN is always correctly set and that
    importing a gnu_inline function over the top of an existing forward
    declaration works correctly.

    The other case that duplicate_decls handles (importing a regular
    definition over the top of a gnu_inline function) doesn't seem like
    something we need to handle specially in modules; we'll just use the
    existing gnu_inline function and rely on the guarantee that there is a
    single non-inline function definition provided elsewhere.

            PR c++/119154

    gcc/cp/ChangeLog:

            * decl2.cc (vague_linkage_p): Revert gnu_linkage handling.
            * module.cc (importer_interface): New enumeration.
            (get_importer_interface): New function.
            (trees_out::core_bools): Use it to determine interface.
            (trees_in::is_matching_decl): Propagate gnu_inline handling onto
            existing forward declarations.
            (trees_in::read_var_def): Also note explicit instantiation
            definitions of variable templates to be emitted.

    gcc/testsuite/ChangeLog:

            * g++.dg/modules/pr119154_a.C: Move to...
            * g++.dg/modules/gnu-inline-1_a.C: ...here, and add decl.
            * g++.dg/modules/pr119154_b.C: Move to...
            * g++.dg/modules/gnu-inline-1_b.C: here, and add check.
            * g++.dg/modules/gnu-inline-1_c.C: New test.
            * g++.dg/modules/gnu-inline-1_d.C: New test.
            * g++.dg/modules/gnu-inline-2_a.C: New test.
            * g++.dg/modules/gnu-inline-2_b.C: New test.
            * g++.dg/modules/extern-tpl-3_a.C: New test.
            * g++.dg/modules/extern-tpl-3_b.C: New test.
            * g++.dg/modules/extern-tpl-4_a.H: New test.
            * g++.dg/modules/extern-tpl-4_b.C: New test.
            * g++.dg/modules/extern-tpl-4_c.C: New test.

    Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Reply via email to