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.

Reply via email to