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; }