This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug lto/60720] clisp fails to build with -flto: internal compiler error: tree check: expected array_type, have record_type in array_ref_low_bound, at expr.c:6941
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 31 Mar 2014 13:13:39 +0000
- Subject: [Bug lto/60720] clisp fails to build with -flto: internal compiler error: tree check: expected array_type, have record_type in array_ref_low_bound, at expr.c:6941
- Auto-submitted: auto-generated
- References: <bug-60720-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60720
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
We miss to wrap uses of non-automatic vars inside MEM_REFs for global
initializers
(we do that for the IL already).
Doing this raises the question whether we shouldn't simply special-case
global var references and stream a type which each reference, materializing
a MEM_REF only when necessary (not sure if we know that at the point we are
materializing the initializer).
Anyway, short-term fix:
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c (revision 208955)
+++ gcc/lto-streamer-out.c (working copy)
@@ -313,6 +313,27 @@ lto_is_streamable (tree expr)
}
+/* Wrap symbol references in *TP inside a type-preserving MEM_REF. */
+
+static tree
+wrap_refs (tree *tp, int *ws, void *)
+{
+ tree t = *tp;
+ if (TREE_CODE (t) == VAR_DECL)
+ {
+ tree ptrtype = build_pointer_type (TREE_TYPE (t));
+ *tp = build2 (MEM_REF, TREE_TYPE (t),
+ build1 (ADDR_EXPR, ptrtype, t),
+ build_int_cst (ptrtype, 0));
+ *ws = 0;
+ }
+ else if (TREE_CODE (t) == CONSTRUCTOR)
+ ;
+ else if (!EXPR_P (t))
+ *ws = 0;
+ return NULL_TREE;
+}
+
/* For EXPR lookup and return what we want to stream to OB as DECL_INITIAL.
*/
static tree
@@ -340,6 +361,14 @@ get_symbol_initial_value (struct output_
initial = error_mark_node;
}
+ /* Wrap all symbol references inside the initializer in a MEM_REF
+ to preserve the type at the use even in case the symbol is
+ prevailed by one with a different type. We can safely skip this
+ during WPA. */
+ if (!in_lto_p
+ && initial && initial != error_mark_node)
+ walk_tree (&initial, wrap_refs, NULL, NULL);
+
return initial;
}