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

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Nathaniel Shead <[email protected]>:

https://gcc.gnu.org/g:c368ea51b3bae27e3007b9bd89f6162c4c80259f

commit r16-6343-gc368ea51b3bae27e3007b9bd89f6162c4c80259f
Author: Nathaniel Shead <[email protected]>
Date:   Fri Dec 5 00:03:46 2025 +1100

    c++/modules: Ignore exposures in lambdas in initializers [PR122994]

    As the PR rightly points out, a lambda is not really a declaration in
    and of itself by the standard, and so a lambda only used in a context
    where exposures are ignored should not itself cause an error.

    This patch implements this by way of a new flag set on deps that are
    first found in an ignored context.  This flag gets cleared if we ever
    see the dep in a context where exposures are not ignored.  Then, while
    walking a declaration with this flag set, we re-establish an ignored
    context.  This is done for all decls (not just lambdas) to handle
    block-scope classes as well.

    Additionally, we prevent walking of attached declarations for a
    DECL_MODULE_KEYED_DECLS_P entity during dependency gathering, so that we
    don't think we've seen the decl at this point.  This means we may not
    have an appropriate entity to stream for this walk; to prevent any
    potential issues with merging we stream a NULL_TREE 'hole' in the vector
    and handle this carefully on import.

    This requires a small amount of testsuite adjustment because we no
    longer diagnose errors we used to.  Because our ABI for inline variables
    with dynamic initialization is to just do the initialization in the
    module's initializer function (and importers only perform the static
    initialization) we don't bother to walk the definition of inline
    variables containing lambdas and so don't see the exposures, despite
    us considering TU-local entities in static initializers of inline
    variables being exposures (see PR c++/119551).  This is legal by the
    current wording of the standard, which does not consider the definition
    of any variable to be an exposure (even an inline one).

            PR c++/122994

    gcc/cp/ChangeLog:

            * module.cc (depset::disc_bits): New flag
            DB_IGNORED_EXPOSURE_BIT.
            (depset::is_ignored_exposure_context): New getter.
            (depset::hash::ignore_tu_local): Rename to...
            (depset::hash::ignore_exposure): ...this, and make private.
            (depset::hash::hash): Rename ignore_tu_local.
            (depset::hash::ignore_exposure_if): New function.
            (trees_out::decl_value): Don't build deps for keyed entities.
            (trees_in::decl_value): Handle missing keys.
            (trees_out::write_function_def): Use ignore_exposure_if.
            (trees_out::write_var_def): Likewise.
            (trees_out::write_class_def): Likewise.
            (depset::hash::make_dependency): Set DB_IGNORED_EXPOSURE_BIT if
            appropriate, or clear it otherwise.
            (depset::hash::add_dependency): Rename ignore_tu_local.
            (depset::hash::find_dependencies): Set ignore_exposure if in
            such a context.

    gcc/testsuite/ChangeLog:

            * g++.dg/modules/internal-17_b.C: Use functions and internal
            types rather than lambdas.
            * g++.dg/modules/internal-4_b.C: Correct expected result.
            * g++.dg/modules/internal-20_a.C: New test.
            * g++.dg/modules/internal-20_b.C: New test.
            * g++.dg/modules/internal-20_c.C: New test.
            * g++.dg/modules/internal-21_a.C: New test.
            * g++.dg/modules/internal-21_b.C: New test.

    Signed-off-by: Nathaniel Shead <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Reply via email to