https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85047
Bug ID: 85047 Summary: cdd2a01 (and others) FAIL with -flto Product: gcc Version: 8.0.1 Status: UNCONFIRMED Keywords: lto Severity: normal Priority: P3 Component: ada Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- They FAIL like /home/abuild/rguenther/obj/gcc/gnatmake --GNATBIND=/home/abuild/rguenther/obj/gcc/gnatbind --GNATLINK=/home/abuild/rguenther/obj/gcc/gnatlink --GCC=/home/abuild/rguenther/obj/gcc/xgcc -B/home/abuild/rguenther/obj/gcc/ -gnatws -O2 -g -flto -gnat95 -I/home/abuild/rguenther/obj/gcc/testsuite/ada/acats/support cdd2a01.adb -largs --GCC=/home/abuild/rguenther/obj/gcc/xgcc -B/home/abuild/rguenther/obj/gcc/ /home/abuild/rguenther/obj/gcc/xgcc -c -B/home/abuild/rguenther/obj/gcc/ -gnatws -O2 -g -flto -gnat95 -I/home/abuild/rguenther/obj/gcc/testsuite/ada/acats/support cdd2a01.adb /home/abuild/rguenther/obj/gcc/gnatbind -I/home/abuild/rguenther/obj/gcc/testsuite/ada/acats/support -x cdd2a01.ali /home/abuild/rguenther/obj/gcc/gnatlink cdd2a01.ali -O2 -g -flto --GCC=/home/abuild/rguenther/obj/gcc/xgcc -B/home/abuild/rguenther/obj/gcc/ cdd2a01.adb: In function â<80><98>cdd2a01â<80><99>: cdd2a01.adb:46:1: error: type mismatch in component reference procedure CDD2A01 is ^ struct cdd2a01__test2__Tx1S__T651b struct cdd2a01__test2__Tx1S__T651b # .MEM_2297 = VDEF <.MEM_2296> x1._parent.c1 = _1146; cdd2a01.adb:46:1: error: type mismatch in component reference struct cdd2a01__test2__B_5__B_6__Ty2S__T748b struct cdd2a01__test2__B_5__B_6__Ty2S__T748b # .MEM_2437 = VDEF <.MEM_2436> y2._parent._tag = _1256; during GIMPLE pass: fixup_cfg ... which is immediately after streaming in the bodies. The assertion is quite simple: if (TREE_CODE (expr) == COMPONENT_REF && !useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (TREE_OPERAND (expr, 1)))) { error ("type mismatch in component reference"); debug_generic_stmt (TREE_TYPE (expr)); debug_generic_stmt (TREE_TYPE (TREE_OPERAND (expr, 1))); return true; so the FIELD_DECLs type is supposed to be trivially convertible to the COMPONENT_REFs type. What happens here is that one of these is variably modified to LTO and thus ends up in the function-local section and one is not and thus indexable. The local types never get canonically "merged" with others (didn't try if that fixes it). I'm not sure how it arrives with inconsistent types, at stream-out time we have <component_ref 0x7ffff5fa00c0 type <integer_type 0x7ffff61ba888 integer ... arg:0 <component_ref 0x7ffff5fa0090 type <record_type 0x7ffff5f87738 cdd2a01__test2__Tx1S__T651b sizes-gimplified asm_written type_2 type_7 BLK ... arg:0 <var_decl 0x7ffff5f73cf0 x1 type <record_type 0x7ffff5f87690 cdd2a01__test2__Tx1S> addressable BLK cdd2a01.adb:298:13 size <integer_cst 0x7ffff6894f48 readonly constant 256> unit-size <integer_cst 0x7ffff68b0048 readonly constant 32> align:128 warn_if_not_align:0 context <function_decl 0x7ffff6198b00 cdd2a01> chain <type_decl 0x7ffff5f8e8e8 cdd2a01__test2__T653b__T654b__TT655bP1___XDLU_8__8>> arg:1 <field_decl 0x7ffff5f8aa18 _parent type <record_type 0x7ffff5f87738 cdd2a01__test2__Tx1S__T651b> so there it looks OK. I presume the fact that we end up with a similar record type "locally" and one globally confuses the tree merging machinery and we end up inserting a FIELD_DECL that was improperly tree-merged. So we first write the type locally from # DEBUG _init => &s and then globally again via write_global_stream where it is reachable from cdd2a01__test2__Tx1S which is output indexed via the local variable x1. So the issue is that a "global" tree references a "local" one -- this is broken and results in duplicates. The situation is all a bit complicated here given we do not put all "local" types into the local stream (local as-in decl_function_context () != NULL) but only variably modified types. It's a bit too much of a change now, but I guess TYPE_CONTEXT isn't set reliably either (consider build_pointer_type_* which doesn't set a context but the context should be probably inherited from the pointed-to context). At least just doing Index: lto-streamer-out.c =================================================================== --- lto-streamer-out.c (revision 258764) +++ lto-streamer-out.c (working copy) @@ -146,7 +146,10 @@ tree_is_indexable (tree t) them we have to localize their members as well. ??? In theory that includes non-FIELD_DECLs as well. */ else if (TYPE_P (t) - && variably_modified_type_p (t, NULL_TREE)) + && (variably_modified_type_p (t, NULL_TREE) + || (TYPE_NAME (t) + && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + && decl_function_context (TYPE_NAME (t))))) return false; else if (TREE_CODE (t) == FIELD_DECL && variably_modified_type_p (DECL_CONTEXT (t), NULL_TREE)) doesn't fix the testcase.