On Sat, Feb 10, 2024 at 08:01:46PM -0800, Andrew Pinski wrote: > On Sat, Feb 10, 2024 at 7:55 PM Nathaniel Shead > <nathanielosh...@gmail.com> wrote: > > > > Bootstrapped and regtested (so far just modules.exp and dg.exp) on > > x86_64-pc-linux-gnu, OK for trunk if full regtest succeeds? > > > > (Also I noticed I forgot to add the PR to the changelog in my last > > patch, I've fixed that locally.) > > > > -- >8 -- > > > > After fixing PR111710, I noticed that we currently ICE when declaring a > > type that derives from 'decltype([]{})'. As far as I can tell this > > should be legal code, since by [basic.link] p15.2 a lambda defined in a > > class-specifier should not be TU-local. > > > > This patch also adds a bunch of tests for unevaluated lambdas in other > > contexts, which generally seem to work now. > > There are many unevaluated lambdas (non-modules related) bugs report > (all linked to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107430). > Do you know if this fixes any of the non-module related ones too? > > Thanks, > Andrew Pinski >
I took a quick look at the issues linked to the above. I tried a few and they don't seem to be fixed with these patches; in general I would only expect changes in modules or potentially with lambdas being used in base class specifiers, neither of which seem particularly relevant to those issues. Nathaniel > > > > One interesting case is 'E::f' in the attached testcase: it appears to > > get a merge kind of 'MK_field', rather than 'MK_keyed' as most other > > lambdas do. I'm not entirely sure if this will cause issues in the > > future, but I haven't been able to construct a testcase that causes > > problems with this, and conversely wrapping the class body in > > 'start_lambda_scope' causes issues with symbol duplication in COMDAT > > groups, so I've left it as-is for now. > > > > gcc/cp/ChangeLog: > > > > * module.cc (trees_out::key_mergeable): Also support TYPE_DECLs. > > (maybe_key_decl): Likewise. > > * parser.cc (cp_parser_class_head): Start a lambda scope when > > parsing base classes. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/modules/lambda-7_a.C: > > * g++.dg/modules/lambda-7_b.C: > > > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > > --- > > gcc/cp/module.cc | 8 +++++--- > > gcc/cp/parser.cc | 10 ++++++++-- > > gcc/testsuite/g++.dg/modules/lambda-7_a.C | 19 +++++++++++++++++++ > > gcc/testsuite/g++.dg/modules/lambda-7_b.C | 23 +++++++++++++++++++++++ > > 4 files changed, 55 insertions(+), 5 deletions(-) > > > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > > index 9742bca922c..cceec79b26b 100644 > > --- a/gcc/cp/module.cc > > +++ b/gcc/cp/module.cc > > @@ -10784,7 +10784,8 @@ trees_out::key_mergeable (int tag, merge_kind mk, > > tree decl, tree inner, > > (TREE_TYPE (inner))); > > gcc_checking_assert (TREE_CODE (scope) == VAR_DECL > > || TREE_CODE (scope) == FIELD_DECL > > - || TREE_CODE (scope) == PARM_DECL); > > + || TREE_CODE (scope) == PARM_DECL > > + || TREE_CODE (scope) == TYPE_DECL); > > auto *root = keyed_table->get (scope); > > unsigned ix = root->length (); > > /* If we don't find it, we'll write a really big number > > @@ -18980,10 +18981,11 @@ maybe_key_decl (tree ctx, tree decl) > > return; > > > > /* We only need to deal with lambdas attached to var, field, > > - or parm decls. */ > > + parm, or type decls. */ > > if (TREE_CODE (ctx) != VAR_DECL > > && TREE_CODE (ctx) != FIELD_DECL > > - && TREE_CODE (ctx) != PARM_DECL) > > + && TREE_CODE (ctx) != PARM_DECL > > + && TREE_CODE (ctx) != TYPE_DECL) > > return; > > > > if (!keyed_table) > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > > index 09ecfa23b5d..151e724ed66 100644 > > --- a/gcc/cp/parser.cc > > +++ b/gcc/cp/parser.cc > > @@ -27663,10 +27663,16 @@ cp_parser_class_head (cp_parser* parser, > > if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) > > { > > if (type) > > - pushclass (type); > > + { > > + pushclass (type); > > + start_lambda_scope (TYPE_NAME (type)); > > + } > > bases = cp_parser_base_clause (parser); > > if (type) > > - popclass (); > > + { > > + finish_lambda_scope (); > > + popclass (); > > + } > > } > > else > > bases = NULL_TREE; > > diff --git a/gcc/testsuite/g++.dg/modules/lambda-7_a.C > > b/gcc/testsuite/g++.dg/modules/lambda-7_a.C > > index 289285cd926..9a23827a280 100644 > > --- a/gcc/testsuite/g++.dg/modules/lambda-7_a.C > > +++ b/gcc/testsuite/g++.dg/modules/lambda-7_a.C > > @@ -18,3 +18,22 @@ export struct S { > > export inline int d(int x, int (*f)(int) = [](int x) { return x * 5; }) { > > return f(x); > > } > > + > > +// unevaluated lambdas > > +#if __cplusplus >= 202002L > > +export struct E : decltype([](int x) { return x * 6; }) { > > + decltype([](int x) { return x * 7; }) f; > > +}; > > + > > +export template <typename T> > > +struct G : decltype([](int x) { return x * 8; }) { > > + decltype([](int x) { return x * 9; }) h; > > +}; > > + > > +template <> > > +struct G<double> : decltype([](int x) { return x * 10; }) { > > + decltype([](int x) { return x * 11; }) i; > > +}; > > + > > +export decltype([](int x) { return x * 12; }) j; > > +#endif > > diff --git a/gcc/testsuite/g++.dg/modules/lambda-7_b.C > > b/gcc/testsuite/g++.dg/modules/lambda-7_b.C > > index a8762399ee1..59a82e05cbf 100644 > > --- a/gcc/testsuite/g++.dg/modules/lambda-7_b.C > > +++ b/gcc/testsuite/g++.dg/modules/lambda-7_b.C > > @@ -13,4 +13,27 @@ int main() { > > __builtin_abort(); > > if (d(10) != 50) > > __builtin_abort(); > > + > > +#if __cplusplus >= 202002L > > + E e; > > + if (e(10) != 60) > > + __builtin_abort(); > > + if (e.f(10) != 70) > > + __builtin_abort(); > > + > > + G<int> g1; > > + if (g1(10) != 80) > > + __builtin_abort(); > > + if (g1.h(10) != 90) > > + __builtin_abort(); > > + > > + G<double> g2; > > + if (g2(10) != 100) > > + __builtin_abort(); > > + if (g2.i(10) != 110) > > + __builtin_abort(); > > + > > + if (j(10) != 120) > > + __builtin_abort(); > > +#endif > > } > > -- > > 2.43.0 > >