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]>
