https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121935
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED CC| |rguenth at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- So the issue with the testcase at hand is that appearantly we fail to visit record_type 0x7ffff69a7888 a during free-lang-data, and that type ends up in the tree stream for function 'e'. We walk function type arguments via if (!RECORD_OR_UNION_TYPE_P (t)) fld_worklist_push (TYPE_CACHED_VALUES (t), fld); It seems we have two 'a': (gdb) p debug_tree (0x7ffff69a7738) <record_type 0x7ffff69a7738 a sizes-gimplified cxx-odr-p type_5 type_6 QI size <integer_cst 0x7ffff681b390 type <integer_type 0x7ffff68230a8 bitsizetype> constant 8> unit-size <integer_cst 0x7ffff681b3a8 type <integer_type 0x7ffff6823000 sizetype> constant 1> align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff69a7738 context <translation_unit_decl 0x7ffff6821000 t.ii>> this one is visited correctly. (gdb) p debug_tree (0x7ffff69a7888) <record_type 0x7ffff69a7888 a sizes-gimplified cxx-odr-p type_5 QI size <integer_cst 0x7ffff681b390 type <integer_type 0x7ffff68230a8 bitsizetype> constant 8> unit-size <integer_cst 0x7ffff681b3a8 type <integer_type 0x7ffff6823000 sizetype> constant 1> align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff69a7738 fields <var_decl 0x7ffff69bb1c8 b type <integer_type 0x7ffff68235e8 int public type_6 SI size <integer_cst 0x7ffff681b4e0 constant 32> unit-size <integer_cst 0x7ffff681b4f8 constant 4> align:32 warn_if_not_align:0 symtab:0 alias-set 2 canonical-type 0x7ffff68235e8 precision:32 min <integer_cst 0x7ffff681b498 -2147483648> max <integer_cst 0x7ffff681b4b0 2147483647> pointer_to_this <pointer_type 0x7ffff682ab28>> readonly public static external nonlocal decl_3 decl_5 decl_6 SI t.ii:2:14 size <integer_cst 0x7ffff681b4e0 32> unit-size <integer_cst 0x7ffff681b4f8 4> align:32 warn_if_not_align:0 context <record_type 0x7ffff69a7738 a> chain <type_decl 0x7ffff6831dc0 a type <record_type 0x7ffff69a7888 a> nonlocal decl_4 VOID t.ii:1:10 align:1 warn_if_not_align:0 context <record_type 0x7ffff69a7738 a> result <record_type 0x7ffff69a7738 a>>> context <translation_unit_decl 0x7ffff6821000 t.ii> chain <type_decl 0x7ffff6831d20 a>> this one is not. It's also not visited without the patch but somehow without it we don't end up streaming it. So the point where it diverges must be somewhere else ... Note the old guard, + if (TREE_CODE (t) != FIELD_DECL + && TREE_CODE (t) != TYPE_DECL) + fld_worklist_push (TREE_CHAIN (t), fld); was because we walk the record-or-union fields manually. But only FIELD_DECLs there, so seeing TYPE_DECL here is odd. That said, I think the change is a good step towards cleaning up the code. We have to figure where we need to walk TREE_CHAIN and walk it with an inclusive condition, not an excluding one. Possibly from the context. We are for example visiting <type_decl 0x7ffff69c06e0 d> here, from the chain of <function_decl 0x7ffff69b1300 e> which both have context <record_type 0x7ffff69c3348 d>. So we clearly do not want to walk the chain of FUNCTION_DECLs. Then we hit PARM_DECLs, and DECL_ARGUMENTS we just stream via the chain: if (TREE_CODE (t) == FUNCTION_DECL) { fld_worklist_push (DECL_ARGUMENTS (t), fld); and fixing that fixes the testcase.