diff mbox series

c++: avoid name lookup during mangling

Message ID 20240209155110.552199-1-ppalka@redhat.com
State New
Headers show
Series c++: avoid name lookup during mangling | expand

Commit Message

Patrick Palka Feb. 9, 2024, 3:51 p.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
reasonable?

-- >8 --

It turns out that with modules we can call mangle_decl recursively,
which is a problem because the global mangling state isn't recursion
aware.  The recursion happens from write_closure_type_name, which calls
lambda function, which performs name lookup, which can trigger lazy
loading, which can call maybe_clone_body for a newly loaded function,
which can inspect DECL_ASSEMBLER_NAME, which enters mangling.  This was
observed when using fmtlib as a module with trunk, and leads to a bogus
"mangling conflicts with a previous mangle error" followed by an ICE
from cdtor_comdat_group due to a mangling mismatch.

I considered making our mangling state recursion-aware, but it seems
this lambda_function call is the only source of name lookup during
mangling, and in turn the only source of potential recursion with
modules so perhaps it's better to just address that.  To that end, this
patch adds a new field to LAMBDA_EXPR holding the op() of the closure
type, so that lambda_function can just inspect this field rather than
having to perform name lookup.  With this patch fmtlib can be
successfully imported as a module (with a few minor source tweaks).

In passing this patch adds streaming of LAMBDA_EXPR_REGEN_INFO which I
noticed is missing.

gcc/cp/ChangeLog:

	* cp-tree.h (LAMBDA_EXPR_FUNCTION): Define.
	(tree_lambda_expr::function): New member.
	* lambda.cc (lambda_function): Use LAMBDA_EXPR_FUNCTION instead
	of performing name lookup.
	* module.cc (trees_out::core_vals): Stream LAMBDA_EXPR_REGEN_INFO
	and LAMBDA_EXPR_FUNCTION.
	(trees_in::core_vals): Likewise.
	* parser.cc (cp_parser_lambda_declarator_opt): Set
	LAMBDA_EXPR_FUNCTION.
	* pt.cc (tsubst_lambda_expr): Likewise.
---
 gcc/cp/cp-tree.h |  5 +++++
 gcc/cp/lambda.cc | 20 +++++---------------
 gcc/cp/module.cc |  4 ++++
 gcc/cp/parser.cc |  1 +
 gcc/cp/pt.cc     |  1 +
 5 files changed, 16 insertions(+), 15 deletions(-)

Comments

Jason Merrill Feb. 9, 2024, 4:19 p.m. UTC | #1
On 2/9/24 10:51, Patrick Palka wrote:
> It turns out that with modules we can call mangle_decl recursively,
> which is a problem because the global mangling state isn't recursion
> aware.  The recursion happens from write_closure_type_name, which calls
> lambda function, which performs name lookup, which can trigger lazy
> loading,

Hmm, why would looking for a member of a closure trigger lazy loading?

Jason
Patrick Palka Feb. 9, 2024, 4:55 p.m. UTC | #2
On Fri, 9 Feb 2024, Jason Merrill wrote:

> On 2/9/24 10:51, Patrick Palka wrote:
> > It turns out that with modules we can call mangle_decl recursively,
> > which is a problem because the global mangling state isn't recursion
> > aware.  The recursion happens from write_closure_type_name, which calls
> > lambda function, which performs name lookup, which can trigger lazy
> > loading,
> 
> Hmm, why would looking for a member of a closure trigger lazy loading?

No idea..  We could sidestep lazy loading here by using
get_class_binding_direct instead of lookup_member in lambda_function,
but I don't know if if that would have unintended consequences.

FWIW the closure for which op() lookup triggers lazy loading is for a
non-generic lambda from an instantiated function template scope and
captures another closure object that captures a dependent function
parameter (_overwrite in libstdc++'s <format> line 1607).  So I'd guess
the entity dependency graph is pretty complicated..

And it seems lazy loading from maybe_lazily_declare can be quite
recursive, I wonder if that's expected?  I attached the full backtrace
that leads mangle_decl recursion, and there's about 15 recursive calls
to maybe_lazily_declare in this backtrace which seem to go through
check_local_shadow.  Maybe we can reduce this somehow?

This is just a naive experiment, but interestingly only two modules
tests fail if we remove the call to lazy_load_pendings from
maybe_lazily_declare:

  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/member-def-1_c.C -std=c++17  scan-lang-dump module "Reading 1 pending entities keyed to '::frob'"
  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/member-def-1_c.C -std=c++2a  scan-lang-dump module "Reading 1 pending entities keyed to '::frob'"
  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/member-def-1_c.C -std=c++2b  scan-lang-dump module "Reading 1 pending entities keyed to '::frob'"
  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/part-6 -std=c++17 link
  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/part-6 -std=c++2a link
  gcc/testsuite/g++/g++.sum:FAIL: g++.dg/modules/part-6 -std=c++2b link

> 
> Jason
> 
>
#0  start_mangling (entity=<function_decl 0x7fffef4ad100 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4315
#1  mangle_decl_string (decl=decl@entry=<function_decl 0x7fffef4ad100 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4415
#2  0x0000000000b29e3b in get_mangled_id (decl=<function_decl 0x7fffef4ad100 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4441
#3  mangle_decl (decl=<function_decl 0x7fffef4ad100 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4479
#4  0x00000000015e9d5e in decl_assembler_name (decl=<function_decl 0x7fffef4ad100 __dt_comp >) at /home/patrick/code/gcc/gcc/tree.cc:719
#5  0x0000000000b8798f in cdtor_comdat_group (complete=<optimized out>, base=base@entry=<function_decl 0x7fffef4ad200 __dt_base >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:177
#6  0x0000000000b89ec3 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef4ad000 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:597
#7  0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#8  0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#9  0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffef4c1888 __formatter_int>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#10 get_class_binding (klass=<record_type 0x7fffef4c1888 __formatter_int>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#11 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef4c5480>, data=data@entry=0x7fffffff7660) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#12 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff7660, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef4c5480>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#13 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef4c1888 __formatter_int>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#14 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffeee18a20) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#15 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#16 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef4d7700 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#17 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#18 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef4d6800 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff7868)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#19 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef4d7700 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#20 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef4d6800 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#21 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef4d6600 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#22 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#23 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#24 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffef51d1f8 __formatter_str>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#25 get_class_binding (klass=<record_type 0x7fffef51d1f8 __formatter_str>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#26 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef4f4cc0>, data=data@entry=0x7fffffff7b90) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#27 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff7b90, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef4f4cc0>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#28 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef51d1f8 __formatter_str>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#29 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffeee18990) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#30 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#31 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef525a80 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#32 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#33 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef526400 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff7d98)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#34 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef525a80 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#35 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef526400 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#36 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef526200 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#37 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#38 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#39 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff73f3340 __r>, klass=<record_type 0x7fffef53a7e0 _Utf_view>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#40 get_class_binding (klass=<record_type 0x7fffef53a7e0 _Utf_view>, name=<identifier_node 0x7ffff73f3340 __r>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#41 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef4fc8f0>, data=data@entry=0x7fffffff80c0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#42 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff80c0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef4fc8f0>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#43 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef53a7e0 _Utf_view>, name=name@entry=<identifier_node 0x7ffff73f3340 __r>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#44 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff73f3340 __r>, scope=scope@entry=0x7fffeee18900) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#45 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff73f3340 __r>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#46 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef536e80 __r>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#47 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#48 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef53d000 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff82c8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#49 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef536e00 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#50 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef53d000 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
--Type <RET> for more, q to quit, c to continue without paging--
#51 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef535e00 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#52 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#53 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#54 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff73f3a80 __i>, klass=<record_type 0x7fffef555930 view_interface>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#55 get_class_binding (klass=<record_type 0x7fffef555930 view_interface>, name=<identifier_node 0x7ffff73f3a80 __i>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#56 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef52d840>, data=data@entry=0x7fffffff85f0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#57 0x0000000000c53505 in dfs_walk_all (data=0x7fffffff85f0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef52d840>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#58 dfs_walk_all (data=0x7fffffff85f0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<optimized out>) at /home/patrick/code/gcc/gcc/cp/search.cc:1519
#59 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef54cf18 _Grapheme_cluster_view>, name=name@entry=<identifier_node 0x7ffff73f3a80 __i>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#60 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff73f3a80 __i>, scope=scope@entry=0x7fffeee18828) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#61 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff73f3a80 __i>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#62 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef554780 __i>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#63 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#64 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef551d00 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff87f8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#65 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef554700 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#66 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef551d00 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#67 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef551b00 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#68 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#69 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#70 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff73e6740 __v>, klass=<record_type 0x7fffef54cf18 _Grapheme_cluster_view>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#71 get_class_binding (klass=<record_type 0x7fffef54cf18 _Grapheme_cluster_view>, name=<identifier_node 0x7ffff73e6740 __v>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#72 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef4fcaf8>, data=data@entry=0x7fffffff8b20) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#73 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff8b20, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef4fcaf8>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#74 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef54cf18 _Grapheme_cluster_view>, name=name@entry=<identifier_node 0x7ffff73e6740 __v>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#75 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff73e6740 __v>, scope=scope@entry=0x7fffeee18798) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#76 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff73e6740 __v>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#77 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef554b80 __v>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#78 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#79 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef556200 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff8d28)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#80 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef554b00 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#81 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef556200 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#82 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef556000 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#83 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#84 0x0000000000b6b44f in lazy_load_pendings (decl=decl@entry=<template_decl 0x7fffefc77980 basic_format_context>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#85 0x0000000000c28378 in lookup_template_class (d1=<optimized out>, d1@entry=<record_type 0x7fffef78be70 basic_format_context>, arglist=<tree_vec 0x7fffeee9cb18>, in_decl=in_decl@entry=<tree 0x0>,
    context=context@entry=<tree 0x0>, entering_scope=entering_scope@entry=1, complain=complain@entry=0) at /home/patrick/code/gcc/gcc/cp/pt.cc:10024
#86 0x0000000000c29ca0 in tsubst_aggr_type_1 (t=<record_type 0x7fffef78be70 basic_format_context>, args=<tree_vec 0x7fffef1b1b90>, complain=0, in_decl=<tree 0x0>, entering_scope=1)
    at /home/patrick/code/gcc/gcc/cp/pt.cc:14174
#87 0x0000000000c2ad32 in tsubst (t=<typename_type 0x7fffef7a89d8 iterator>, args=<tree_vec 0x7fffef1b1b90>, complain=0, in_decl=<tree 0x0>) at /home/patrick/code/gcc/gcc/cp/pt.cc:16776
#88 0x0000000000af96fd in dump_template_bindings (parms=<tree 0x0>, args=<tree_vec 0x7fffef1b1b90>, typenames=0x7fffeee9caf0 = {...}, pp=0x31bae40 <actual_pretty_printer>)
    at /home/patrick/code/gcc/gcc/cp/error.cc:494
#89 0x0000000000af2877 in dump_function_decl (t=<template_decl 0x7fffef7a1980 format>, flags=116, pp=0x31bae40 <actual_pretty_printer>) at /home/patrick/code/gcc/gcc/cp/error.cc:1878
#90 0x0000000000afa241 in decl_as_string (decl=decl@entry=<function_decl 0x7fffef1b3900 format>, flags=116) at /home/patrick/code/gcc/gcc/cp/error.cc:3223
#91 0x0000000000c4b4c1 in cxx_print_decl (file=0x7ffff7aaf6a0 <_IO_2_1_stderr_>, node=<function_decl 0x7fffef1b3900 format>, indent=0) at /home/patrick/code/gcc/gcc/cp/ptree.cc:53
#92 0x00000000011ff995 in print_node (file=0x7ffff7aaf6a0 <_IO_2_1_stderr_>, prefix=prefix@entry=0x27022bf "", node=<optimized out>, node@entry=<function_decl 0x7fffef1b3900 format>, indent=indent@entry=0,
    brief_for_visited=brief_for_visited@entry=true) at /home/patrick/code/gcc/gcc/print-tree.cc:572
#93 0x00000000012028ae in debug_tree (node=<function_decl 0x7fffef1b3900 format>) at /home/patrick/code/gcc/gcc/print-tree.cc:1145
#94 <function called from gdb>
#95 start_mangling (entity=<function_decl 0x7fffef18cf00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4315
#96 mangle_decl_string (decl=decl@entry=<function_decl 0x7fffef18cf00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4415
#97 0x0000000000b29e3b in get_mangled_id (decl=<function_decl 0x7fffef18cf00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4441
#98 mangle_decl (decl=<function_decl 0x7fffef18cf00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4479
#99 0x00000000015e9d5e in decl_assembler_name (decl=<function_decl 0x7fffef18cf00 __dt_comp >) at /home/patrick/code/gcc/gcc/tree.cc:719
--Type <RET> for more, q to quit, c to continue without paging--
#100 0x0000000000b8798f in cdtor_comdat_group (complete=<optimized out>, base=base@entry=<function_decl 0x7fffef192000 __dt_base >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:177
#101 0x0000000000b89ec3 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef18ce00 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:597
#102 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#103 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#104 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff7221540 operator()>, klass=<record_type 0x7fffef1b2d20 ._anon_234>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#105 get_class_binding (klass=<record_type 0x7fffef1b2d20 ._anon_234>, name=<identifier_node 0x7ffff7221540 operator()>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#106 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef19de40>, data=data@entry=0x7fffffff9780) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#107 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff9780, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef19de40>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#108 lookup_member (xbasetype=<optimized out>, name=<identifier_node 0x7ffff7221540 operator()>, protect=protect@entry=0, want_type=want_type@entry=false, complain=complain@entry=3, afi=afi@entry=0x0)
    at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#109 0x0000000000b116f2 in lambda_function (lambda=lambda@entry=<record_type 0x7fffef1b2d20 ._anon_234>) at /home/patrick/code/gcc/gcc/cp/lambda.cc:178
#110 0x0000000000b200ef in write_closure_type_name (type=<record_type 0x7fffef1b2d20 ._anon_234>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:1984
#111 write_unqualified_name (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:1591
#112 0x0000000000b24455 in write_local_name (entity=<optimized out>, local_entity=<optimized out>, function=<optimized out>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:2353
#113 write_name (decl=<type_decl 0x7fffef1ac4c0 ._anon_234>, ignore_local_scope=<optimized out>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:1159
#114 0x0000000000b26613 in write_class_enum_type (type=<record_type 0x7fffef1b2d20 ._anon_234>) at /home/patrick/code/gcc/gcc/tree.h:3768
#115 write_type (type=<record_type 0x7fffef1b2d20 ._anon_234>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:2515
#116 0x0000000000b259cd in write_template_args (args=<tree_vec 0x7fffef1af9a0>, parms=<optimized out>, parms@entry=<tree 0x0>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:3228
#117 0x0000000000b2601f in write_nested_name (decl=<function_decl 0x7fffef1b3b00 __resize_and_overwrite>) at /home/patrick/code/gcc/gcc/tree.h:3613
#118 0x0000000000b23a07 in write_encoding (decl=<function_decl 0x7fffef1b3b00 __resize_and_overwrite>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:938
#119 0x0000000000b243bb in write_local_name (entity=<optimized out>, local_entity=<optimized out>, function=<function_decl 0x7fffef1b3b00 __resize_and_overwrite>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:2331
#120 write_name (decl=<function_decl 0x7fffef1b3e00 __dt_comp >, ignore_local_scope=<optimized out>) at /home/patrick/code/gcc/gcc/cp/mangle.cc:1159
#121 0x0000000000b23a07 in write_encoding (decl=<function_decl 0x7fffef1b3e00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:938
#122 0x0000000000b23bac in write_mangled_name (decl=decl@entry=<function_decl 0x7fffef1b3e00 __dt_comp >, top_level=top_level@entry=true) at /home/patrick/code/gcc/gcc/cp/mangle.cc:820
#123 0x0000000000b29c51 in mangle_decl_string (decl=decl@entry=<function_decl 0x7fffef1b3e00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4420
#124 0x0000000000b29e3b in get_mangled_id (decl=<function_decl 0x7fffef1b3e00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4441
#125 mangle_decl (decl=<function_decl 0x7fffef1b3e00 __dt_comp >) at /home/patrick/code/gcc/gcc/cp/mangle.cc:4479
#126 0x00000000015e9d5e in decl_assembler_name (decl=<function_decl 0x7fffef1b3e00 __dt_comp >) at /home/patrick/code/gcc/gcc/tree.cc:719
#127 0x0000000000b8798f in cdtor_comdat_group (complete=<optimized out>, base=base@entry=<function_decl 0x7fffef1b3f00 __dt_base >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:177
#128 0x0000000000b89ec3 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef1b3d00 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:597
#129 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#130 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#131 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffef1d9f18 _Terminator>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#132 get_class_binding (klass=<record_type 0x7fffef1d9f18 _Terminator>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#133 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef1d1c00>, data=data@entry=0x7fffffff9d80) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#134 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffff9d80, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef1d1c00>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#135 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef1d9f18 _Terminator>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#136 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffeee183a8) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#137 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#138 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef1d7e00 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#139 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#140 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef1d8e00 __dt_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffff9f88)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#141 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef1d7e00 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#142 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef1d8e00 __dt_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#143 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef1d8c00 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#144 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#145 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#146 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffef243e70 formatter>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#147 get_class_binding (klass=<record_type 0x7fffef243e70 formatter>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#148 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef245120>, data=data@entry=0x7fffffffa2b0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#149 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffa2b0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef245120>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#150 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef243e70 formatter>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#151 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffef114f78) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
--Type <RET> for more, q to quit, c to continue without paging--
#152 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#153 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef23ea00 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#154 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#155 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef239b00 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffa4b8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#156 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef23ea00 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#157 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef239b00 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#158 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef239900 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#159 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#160 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#161 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff70ab340 __str>, klass=<record_type 0x7fffef246b28 _Formatting_scanner>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#162 get_class_binding (klass=<record_type 0x7fffef246b28 _Formatting_scanner>, name=<identifier_node 0x7ffff70ab340 __str>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#163 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffef201ea0>, data=data@entry=0x7fffffffa7e0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#164 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffa7e0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffef201ea0>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#165 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffef246b28 _Formatting_scanner>, name=name@entry=<identifier_node 0x7ffff70ab340 __str>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#166 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff70ab340 __str>, scope=scope@entry=0x7fffef114ee8) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#167 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff70ab340 __str>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#168 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffef255300 __str>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#169 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#170 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffef254300 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffa9e8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#171 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffef255200 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#172 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffef254300 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#173 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffef254100 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#174 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#175 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#176 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff703b380 __rep>, klass=<record_type 0x7fffefefd348 duration>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#177 get_class_binding (klass=<record_type 0x7fffefefd348 duration>, name=<identifier_node 0x7ffff703b380 __rep>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#178 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffefed6d80>, data=data@entry=0x7fffffffad10) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#179 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffad10, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffefed6d80>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#180 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffefefd348 duration>, name=name@entry=<identifier_node 0x7ffff703b380 __rep>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#181 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff703b380 __rep>, scope=scope@entry=0x7fffefdd5990) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#182 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff703b380 __rep>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#183 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffefef8c00 __rep>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#184 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#185 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffefeff100 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffaf18)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#186 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffefef8b80 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#187 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffefeff100 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#188 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffefef7f00 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#189 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#190 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#191 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff0071c40 __dur>, klass=<record_type 0x7fffefe28dc8 time_point>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#192 get_class_binding (klass=<record_type 0x7fffefe28dc8 time_point>, name=<identifier_node 0x7ffff0071c40 __dur>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#193 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffefde1d80>, data=data@entry=0x7fffffffb240) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#194 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffb240, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffefde1d80>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#195 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffefe28dc8 time_point>, name=name@entry=<identifier_node 0x7ffff0071c40 __dur>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#196 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff0071c40 __dur>, scope=scope@entry=0x7fffefdd5678) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#197 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff0071c40 __dur>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#198 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffefe37300 __dur>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#199 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
--Type <RET> for more, q to quit, c to continue without paging--
#200 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffefe35700 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffb448)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#201 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffefe37280 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#202 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffefe35700 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#203 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffefe35500 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#204 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#205 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#206 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffefe69dc8 __shared_ptr_access>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#207 get_class_binding (klass=<record_type 0x7fffefe69dc8 __shared_ptr_access>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#208 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffefe414e0>, data=data@entry=0x7fffffffb770) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#209 0x0000000000c53505 in dfs_walk_all (data=0x7fffffffb770, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffefe414e0>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#210 dfs_walk_all (data=0x7fffffffb770, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<optimized out>) at /home/patrick/code/gcc/gcc/cp/search.cc:1519
#211 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffefe45540 __shared_ptr>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#212 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffefdd55e8) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#213 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#214 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffefe61580 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#215 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#216 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffefe60700 __dt_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffb978)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#217 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffefe61580 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#218 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffefe60700 __dt_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#219 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffefe60500 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#220 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#221 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#222 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7fffefe45540 __shared_ptr>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#223 get_class_binding (klass=<record_type 0x7fffefe45540 __shared_ptr>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#224 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7fffefe43618>, data=data@entry=0x7fffffffbca0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#225 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffbca0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7fffefe43618>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#226 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7fffefe45540 __shared_ptr>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#227 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7fffefdd5510) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#228 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#229 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7fffefe68700 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#230 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#231 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffefe6b300 __ct_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffbea8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
#232 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7fffefe68700 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#233 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffefe6b300 __ct_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#234 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7fffefe6b100 __ct >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#235 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#236 0x0000000000b6b44f in lazy_load_pendings (decl=<optimized out>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#237 0x0000000000b75059 in maybe_lazily_declare (name=<identifier_node 0x7ffff721e840 this>, klass=<record_type 0x7ffff050aa80 shared_ptr>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2002
#238 get_class_binding (klass=<record_type 0x7ffff050aa80 shared_ptr>, name=<identifier_node 0x7ffff721e840 this>, want_type=<optimized out>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:2038
#239 0x0000000000c5313f in lookup_field_r (binfo=binfo@entry=<tree_binfo 0x7ffff041a750>, data=data@entry=0x7fffffffc1d0) at /home/patrick/code/gcc/gcc/cp/search.cc:1061
#240 0x0000000000c533d7 in dfs_walk_all (data=0x7fffffffc1d0, post_fn=0x0, pre_fn=0xc530e0 <lookup_field_r(tree, void*)>, binfo=<tree_binfo 0x7ffff041a750>) at /home/patrick/code/gcc/gcc/cp/search.cc:1507
#241 lookup_member (xbasetype=<optimized out>, xbasetype@entry=<record_type 0x7ffff050aa80 shared_ptr>, name=name@entry=<identifier_node 0x7ffff721e840 this>, protect=protect@entry=2,
    want_type=want_type@entry=true, complain=complain@entry=3, afi=afi@entry=0x0) at /home/patrick/code/gcc/gcc/cp/search.cc:1216
#242 0x0000000000b70340 in get_class_binding (name=name@entry=<identifier_node 0x7ffff721e840 this>, scope=scope@entry=0x7ffff3e27b40) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:5615
#243 0x0000000000b7a160 in outer_binding (name=<identifier_node 0x7ffff721e840 this>, binding=binding@entry=0x0, class_p=class_p@entry=true) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:7715
#244 0x0000000000b7ef2d in check_local_shadow (decl=decl@entry=<parm_decl 0x7ffff05ff500 this>) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:3280
#245 0x0000000000b8493f in pushdecl (decl=<optimized out>, hiding=hiding@entry=false) at /home/patrick/code/gcc/gcc/cp/name-lookup.cc:4007
#246 0x0000000000ab6791 in do_push_parm_decls (decl=decl@entry=<function_decl 0x7fffefd7e000 __dt_base >, args=<optimized out>, nonparms=nonparms@entry=0x7fffffffc3d8)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18214
--Type <RET> for more, q to quit, c to continue without paging--
#247 0x0000000000ab6813 in store_parm_decls (current_function_parms=current_function_parms@entry=<parm_decl 0x7ffff05ff500 this>) at /home/patrick/code/gcc/gcc/cp/decl.cc:18259
#248 0x0000000000ab7311 in start_preparsed_function (decl1=decl1@entry=<function_decl 0x7fffefd7e000 __dt_base >, attrs=attrs@entry=<tree 0x0>, flags=flags@entry=1)
    at /home/patrick/code/gcc/gcc/cp/decl.cc:18115
#249 0x0000000000b894e8 in maybe_clone_body (fn=fn@entry=<function_decl 0x7ffff05fde00 __dt >) at /home/patrick/code/gcc/gcc/cp/optimize.cc:581
#250 0x0000000000b40486 in post_load_processing () at /home/patrick/code/gcc/gcc/cp/module.cc:17548
#251 0x0000000000b6b44f in lazy_load_pendings (decl=decl@entry=<template_decl 0x7ffff6ab7d00 vector>) at /home/patrick/code/gcc/gcc/cp/module.cc:19281
#252 0x0000000000c28378 in lookup_template_class (d1=<optimized out>, d1@entry=<template_decl 0x7ffff6ab7d00 vector>, arglist=arglist@entry=<tree_vec 0x7ffff3c42f40>, in_decl=in_decl@entry=<tree 0x0>,
    context=context@entry=<tree 0x0>, entering_scope=entering_scope@entry=0, complain=3, complain@entry=35) at /home/patrick/code/gcc/gcc/cp/pt.cc:10024
#253 0x0000000000c5fe9e in finish_template_type (name=name@entry=<template_decl 0x7ffff6ab7d00 vector>, args=args@entry=<tree_vec 0x7ffff3c42f40>, entering_scope=0)
    at /home/patrick/code/gcc/gcc/cp/semantics.cc:3948
#254 0x0000000000bca179 in cp_parser_template_id (parser=parser@entry=0x7ffff739be70, template_keyword_p=<optimized out>, check_dependency_p=check_dependency_p@entry=true, tag_type=tag_type@entry=none_type,
    is_declaration=<optimized out>) at /home/patrick/code/gcc/gcc/cp/parser.cc:19039
#255 0x0000000000bca3dc in cp_parser_class_name (parser=parser@entry=0x7ffff739be70, typename_keyword_p=typename_keyword_p@entry=false, template_keyword_p=template_keyword_p@entry=false,
    tag_type=tag_type@entry=none_type, check_dependency_p=check_dependency_p@entry=true, class_head_p=class_head_p@entry=false, is_declaration=false, enum_ok=true)
    at /home/patrick/code/gcc/gcc/cp/parser.cc:26640
#256 0x0000000000bc2ecb in cp_parser_qualifying_entity (is_declaration=false, type_p=false, check_dependency_p=true, template_keyword_p=false, typename_keyword_p=false, parser=0x7ffff739be70)
    at /home/patrick/code/gcc/gcc/cp/parser.cc:7392
#257 cp_parser_nested_name_specifier_opt (parser=parser@entry=0x7ffff739be70, typename_keyword_p=typename_keyword_p@entry=false, check_dependency_p=check_dependency_p@entry=true, type_p=type_p@entry=false,
    is_declaration=is_declaration@entry=false, template_keyword_p=<optimized out>, template_keyword_p@entry=false) at /home/patrick/code/gcc/gcc/cp/parser.cc:7074
#258 0x0000000000bd12e3 in cp_parser_simple_type_specifier (parser=parser@entry=0x7ffff739be70, decl_specs=decl_specs@entry=0x7fffffffccf0, flags=flags@entry=1) at /home/patrick/code/gcc/gcc/cp/parser.cc:20482
#259 0x0000000000baba2a in cp_parser_type_specifier (parser=parser@entry=0x7ffff739be70, flags=flags@entry=1, decl_specs=decl_specs@entry=0x7fffffffccf0, is_declaration=is_declaration@entry=true,
    declares_class_or_enum=0x7fffffffcb80, is_cv_qualifier=is_cv_qualifier@entry=0x7fffffffcb7f) at /home/patrick/code/gcc/gcc/cp/parser.cc:20134
#260 0x0000000000bad75d in cp_parser_decl_specifier_seq (parser=parser@entry=0x7ffff739be70, flags=flags@entry=1, decl_specs=decl_specs@entry=0x7fffffffccf0,
    declares_class_or_enum=declares_class_or_enum@entry=0x7fffffffccb0) at /home/patrick/code/gcc/gcc/cp/parser.cc:16581
#261 0x0000000000bae915 in cp_parser_simple_declaration (parser=0x7ffff739be70, function_definition_allowed_p=false, maybe_range_for_decl=0x0) at /home/patrick/code/gcc/gcc/cp/parser.cc:15765
#262 0x0000000000bd3661 in cp_parser_declaration_statement (parser=<optimized out>) at /home/patrick/code/gcc/gcc/cp/parser.cc:14928
#263 0x0000000000bdb11f in cp_parser_statement (parser=parser@entry=0x7ffff739be70, in_statement_expr=in_statement_expr@entry=<tree 0x0>, in_compound=in_compound@entry=true, if_p=if_p@entry=0x0,
    chain=chain@entry=0x0, loc_after_labels=loc_after_labels@entry=0x0) at /home/patrick/code/gcc/gcc/cp/parser.cc:12884
#264 0x0000000000bb18c8 in cp_parser_statement_seq_opt (parser=parser@entry=0x7ffff739be70, in_statement_expr=in_statement_expr@entry=<tree 0x0>) at /home/patrick/code/gcc/gcc/cp/parser.cc:13410
#265 0x0000000000bb1af8 in cp_parser_compound_statement (parser=parser@entry=0x7ffff739be70, in_statement_expr=in_statement_expr@entry=<tree 0x0>, bcs_flags=bcs_flags@entry=0,
    function_body=function_body@entry=true) at /home/patrick/code/gcc/gcc/cp/parser.cc:13264
#266 0x0000000000bd37d5 in cp_parser_function_body (in_function_try_block=false, parser=0x7ffff739be70) at /home/patrick/code/gcc/gcc/cp/parser.cc:25971
#267 cp_parser_ctor_initializer_opt_and_function_body (parser=0x7ffff739be70, in_function_try_block=false) at /home/patrick/code/gcc/gcc/cp/parser.cc:26022
#268 0x0000000000bd8a4f in cp_parser_function_definition_after_declarator (parser=parser@entry=0x7ffff739be70, inline_p=inline_p@entry=false) at /home/patrick/code/gcc/gcc/cp/parser.cc:32697
#269 0x0000000000bd9bd8 in cp_parser_function_definition_from_specifiers_and_declarator (declarator=<optimized out>, attributes=<tree 0x0>, decl_specifiers=0x7fffffffcf80, parser=0x7ffff739be70)
    at /home/patrick/code/gcc/gcc/cp/parser.cc:32615
#270 cp_parser_init_declarator (parser=parser@entry=0x7ffff739be70, flags=<optimized out>, flags@entry=0, decl_specifiers=decl_specifiers@entry=0x7fffffffd260, checks=checks@entry=0x0,
    function_definition_allowed_p=function_definition_allowed_p@entry=true, member_p=member_p@entry=false, declares_class_or_enum=0, function_definition_p=0x7fffffffd300, maybe_range_for_decl=0x0,
    init_loc=0x7fffffffd224, auto_result=0x7fffffffd3a0) at /home/patrick/code/gcc/gcc/cp/parser.cc:23358
#271 0x0000000000baea69 in cp_parser_simple_declaration (parser=0x7ffff739be70, function_definition_allowed_p=true, maybe_range_for_decl=0x0) at /home/patrick/code/gcc/gcc/cp/parser.cc:15892
#272 0x0000000000be67c4 in cp_parser_declaration (parser=0x7ffff739be70, prefix_attrs=<tree 0x0>) at /home/patrick/code/gcc/gcc/cp/parser.cc:15565
#273 0x0000000000be71fb in cp_parser_toplevel_declaration (parser=0x7ffff739be70) at /home/patrick/code/gcc/gcc/cp/parser.cc:15586
#274 cp_parser_translation_unit (parser=0x7ffff739be70) at /home/patrick/code/gcc/gcc/cp/parser.cc:5278
#275 c_parse_file () at /home/patrick/code/gcc/gcc/cp/parser.cc:51176
#276 0x0000000000d32512 in c_common_parse_file () at /home/patrick/code/gcc/gcc/c-family/c-opts.cc:1306
#277 0x00000000012e81be in compile_file () at /home/patrick/code/gcc/gcc/toplev.cc:447
#278 0x0000000000a00bfc in do_compile () at /home/patrick/code/gcc/gcc/toplev.cc:2152
#279 toplev::main (this=this@entry=0x7fffffffd65e, argc=<optimized out>, argc@entry=35, argv=<optimized out>, argv@entry=0x7fffffffd788) at /home/patrick/code/gcc/gcc/toplev.cc:2308
#280 0x0000000000a023db in main (argc=35, argv=0x7fffffffd788) at /home/patrick/code/gcc/gcc/main.cc:39
Jason Merrill Feb. 9, 2024, 6:17 p.m. UTC | #3
On 2/9/24 11:55, Patrick Palka wrote:
> On Fri, 9 Feb 2024, Jason Merrill wrote:
> 
>> On 2/9/24 10:51, Patrick Palka wrote:
>>> It turns out that with modules we can call mangle_decl recursively,
>>> which is a problem because the global mangling state isn't recursion
>>> aware.  The recursion happens from write_closure_type_name, which calls
>>> lambda function, which performs name lookup, which can trigger lazy
>>> loading,
>>
>> Hmm, why would looking for a member of a closure trigger lazy loading?
> 
> No idea..  We could sidestep lazy loading here by using
> get_class_binding_direct instead of lookup_member in lambda_function,
> but I don't know if if that would have unintended consequences.

Seems worth trying; the lazy load should still get triggered by some 
other name lookup.

> FWIW the closure for which op() lookup triggers lazy loading is for a
> non-generic lambda from an instantiated function template scope and
> captures another closure object that captures a dependent function
> parameter (_overwrite in libstdc++'s <format> line 1607).  So I'd guess
> the entity dependency graph is pretty complicated..
> 
> And it seems lazy loading from maybe_lazily_declare can be quite
> recursive, I wonder if that's expected?  I attached the full backtrace
> that leads mangle_decl recursion, and there's about 15 recursive calls
> to maybe_lazily_declare in this backtrace which seem to go through
> check_local_shadow.  Maybe we can reduce this somehow?

I think we shouldn't bother with check_local_shadow in a clone or 
instantiation, only when actually parsing.

Jason
Patrick Palka Feb. 9, 2024, 9:56 p.m. UTC | #4
On Fri, 9 Feb 2024, Jason Merrill wrote:

> On 2/9/24 11:55, Patrick Palka wrote:
> > On Fri, 9 Feb 2024, Jason Merrill wrote:
> > 
> > > On 2/9/24 10:51, Patrick Palka wrote:
> > > > It turns out that with modules we can call mangle_decl recursively,
> > > > which is a problem because the global mangling state isn't recursion
> > > > aware.  The recursion happens from write_closure_type_name, which calls
> > > > lambda function, which performs name lookup, which can trigger lazy
> > > > loading,
> > > 
> > > Hmm, why would looking for a member of a closure trigger lazy loading?
> > 
> > No idea..  We could sidestep lazy loading here by using
> > get_class_binding_direct instead of lookup_member in lambda_function,
> > but I don't know if if that would have unintended consequences.
> 
> Seems worth trying; the lazy load should still get triggered by some other
> name lookup.

Makes sense.

> 
> > FWIW the closure for which op() lookup triggers lazy loading is for a
> > non-generic lambda from an instantiated function template scope and
> > captures another closure object that captures a dependent function
> > parameter (_overwrite in libstdc++'s <format> line 1607).  So I'd guess
> > the entity dependency graph is pretty complicated..
> > 
> > And it seems lazy loading from maybe_lazily_declare can be quite
> > recursive, I wonder if that's expected?  I attached the full backtrace
> > that leads mangle_decl recursion, and there's about 15 recursive calls
> > to maybe_lazily_declare in this backtrace which seem to go through
> > check_local_shadow.  Maybe we can reduce this somehow?
> 
> I think we shouldn't bother with check_local_shadow in a clone or
> instantiation, only when actually parsing.

Ah, this idea seems to work very nicely.  I posted a new patch
implementing them at
https://gcc.gnu.org/pipermail/gcc-patches/2024-February/645307.html (and
a follow-up patch fixing two small bugs caught by testing fmtlib with
newer -std).
diff mbox series

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 969c7239c97..3bef35fd90c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1543,6 +1543,10 @@  enum cp_lambda_default_capture_mode_type {
 #define LAMBDA_EXPR_CLOSURE(NODE) \
   (TREE_TYPE (LAMBDA_EXPR_CHECK (NODE)))
 
+/* The op() of the lambda closure type as would be found by name lookup.  */
+#define LAMBDA_EXPR_FUNCTION(NODE) \
+  (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->function)
+
 struct GTY (()) tree_lambda_expr
 {
   struct tree_typed typed;
@@ -1550,6 +1554,7 @@  struct GTY (()) tree_lambda_expr
   tree this_capture;
   tree extra_scope;
   tree regen_info;
+  tree function;
   vec<tree, va_gc> *pending_proxies;
   location_t locus;
   enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 1d37e5a52b9..c3ec9381c19 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -165,22 +165,12 @@  begin_lambda_type (tree lambda)
 tree
 lambda_function (tree lambda)
 {
-  tree type;
-  if (TREE_CODE (lambda) == LAMBDA_EXPR)
-    type = LAMBDA_EXPR_CLOSURE (lambda);
-  else
-    type = lambda;
-  gcc_assert (LAMBDA_TYPE_P (type));
-  /* Don't let debug_tree cause instantiation.  */
-  if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
-      && !COMPLETE_OR_OPEN_TYPE_P (type))
+  if (CLASS_TYPE_P (lambda))
+    lambda = CLASSTYPE_LAMBDA_EXPR (lambda);
+  tree callop = LAMBDA_EXPR_FUNCTION (lambda);
+  if (!callop)
     return NULL_TREE;
-  lambda = lookup_member (type, call_op_identifier,
-			  /*protect=*/0, /*want_type=*/false,
-			  tf_warning_or_error);
-  if (lambda)
-    lambda = STRIP_TEMPLATE (get_first_fn (lambda));
-  return lambda;
+  return STRIP_TEMPLATE (callop);
 }
 
 /* True if EXPR is an expression whose type can be used directly in lambda
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 3c2fef0e3f4..7ae965d38e4 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6317,6 +6317,8 @@  trees_out::core_vals (tree t)
       WT (((lang_tree_node *)t)->lambda_expression.capture_list);
       WT (((lang_tree_node *)t)->lambda_expression.this_capture);
       WT (((lang_tree_node *)t)->lambda_expression.extra_scope);
+      WT (((lang_tree_node *)t)->lambda_expression.regen_info);
+      WT (((lang_tree_node *)t)->lambda_expression.function);
       /* pending_proxies is a parse-time thing.  */
       gcc_assert (!((lang_tree_node *)t)->lambda_expression.pending_proxies);
       if (state)
@@ -6818,6 +6820,8 @@  trees_in::core_vals (tree t)
       RT (((lang_tree_node *)t)->lambda_expression.capture_list);
       RT (((lang_tree_node *)t)->lambda_expression.this_capture);
       RT (((lang_tree_node *)t)->lambda_expression.extra_scope);
+      RT (((lang_tree_node *)t)->lambda_expression.regen_info);
+      RT (((lang_tree_node *)t)->lambda_expression.function);
       /* lambda_expression.pending_proxies is NULL  */
       ((lang_tree_node *)t)->lambda_expression.locus
 	= state->read_location (*this);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index c4292c49ce2..3fe975cc213 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -12111,6 +12111,7 @@  cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     else if (parser->fully_implicit_function_template_p)
       fco = finish_fully_implicit_template (parser, fco);
 
+    LAMBDA_EXPR_FUNCTION (lambda_expr) = fco;
     finish_member_declaration (fco);
     record_lambda_scope_sig_discriminator (lambda_expr, fco);
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f9abb21a9a2..5743b105af3 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19719,6 +19719,7 @@  tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	  r = error_mark_node;
 	  goto out;
 	}
+      LAMBDA_EXPR_FUNCTION (r) = inst;
       finish_member_declaration (inst);
       record_lambda_scope_sig_discriminator (r, inst);