On 1/31/25 8:46 AM, Nathaniel Shead wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?Happy to remove the custom inform for lambdas, but I felt that the original message (which suggests that defining it within a class should make it OK) was unhelpful here. Similarly the 'is_exposure_of_member_type' function is not necessary to fix the bug, and is just for slightly nicer diagnostics. -- >8 -- Previously, 'is_tu_local_entity' wouldn't detect the exposure of the (in practice) TU-local lambda in the following example, unless instantiated: struct S { template <typename> static inline decltype([]{}) x = {}; }; This is for two reasons. Firstly, when traversing the TYPE_FIELDS of S we only see the TEMPLATE_DECL, and never end up building a dependency on its DECL_TEMPLATE_RESULT (due to not being instantiated). This patch fixes this by stripping any templates before checking for unnamed types. The second reason is that we currently assume all class-scope entities are not TU-local. Despite this being unambiguous in the standard, this is not actually true in our implementation just yet, due to issues with mangling lambdas in some circumstances. Allowing these lambdas to be exported can cause issues in importers with apparently conflicting declarations, so this patch treats them as TU-local as well. After these changes, we now get double diagnostics from the two ways that we can see the above lambda being exposed, via 'S' (through TYPE_FIELDS) or via 'S::x'. To workaround this we hide diagnostics from the first case, so we only get errors from 'S::x' which will be closer to the point the offending lambda is declared. gcc/cp/ChangeLog: * module.cc (trees_out::type_node): Adjust assertion. (depset::hash::is_tu_local_entity): Handle unnamed template types, treat lambdas specially. (is_exposure_of_member_type): New function. (depset::hash::add_dependency): Use it. (depset::hash::finalize_dependencies): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-10.C: New test. Signed-off-by: Nathaniel Shead <[email protected]> --- gcc/cp/module.cc | 67 ++++++++++++++++++---- gcc/testsuite/g++.dg/modules/internal-10.C | 25 ++++++++ 2 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/internal-10.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c89834c1abd..59b7270f4a5 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -9261,7 +9261,9 @@ trees_out::type_node (tree type)/* We'll have either visited this type or have newly discoveredthat it's TU-local; either way we won't need to visit it again. */ - gcc_checking_assert (TREE_VISITED (type) || has_tu_local_dep (name)); + gcc_checking_assert (TREE_VISITED (type) + || has_tu_local_dep (TYPE_NAME (type)) + || has_tu_local_dep (TYPE_TI_TEMPLATE (type)));
Why doesn't the template having a TU-local dep imply that the TYPE_NAME does?
Jason
