re PR 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)

2014-04-14  Richard Biener  <rguenther@suse.de>

	PR lto/60720
	* lto-streamer-out.c (wrap_refs): New function.
	(lto_output): Wrap symbol references in global initializes in
	type-preserving MEM_REFs.

	* gcc.dg/lto/pr60720_0.c: New testcase.
	* gcc.dg/lto/pr60720_1.c: Likewise.

From-SVN: r209359
This commit is contained in:
Richard Biener 2014-04-14 08:35:22 +00:00
parent 9447df74c0
commit 8359c87e12
5 changed files with 77 additions and 16 deletions

View File

@ -1,3 +1,10 @@
2014-04-14 Richard Biener <rguenther@suse.de>
PR lto/60720
* lto-streamer-out.c (wrap_refs): New function.
(lto_output): Wrap symbol references in global initializes in
type-preserving MEM_REFs.
2014-04-14 Christian Bruel <christian.bruel@st.com> 2014-04-14 Christian Bruel <christian.bruel@st.com>
* config/sh/sh-mem.cc (sh_expand_strlen): Unroll last word. * config/sh/sh-mem.cc (sh_expand_strlen): Unroll last word.

View File

@ -2022,6 +2022,29 @@ copy_function (struct cgraph_node *node)
lto_end_section (); lto_end_section ();
} }
/* Wrap symbol references in *TP inside a type-preserving MEM_REF. */
static tree
wrap_refs (tree *tp, int *ws, void *)
{
tree t = *tp;
if (handled_component_p (t)
&& TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
{
tree decl = TREE_OPERAND (t, 0);
tree ptrtype = build_pointer_type (TREE_TYPE (decl));
TREE_OPERAND (t, 0) = build2 (MEM_REF, TREE_TYPE (decl),
build1 (ADDR_EXPR, ptrtype, decl),
build_int_cst (ptrtype, 0));
TREE_THIS_VOLATILE (TREE_OPERAND (t, 0)) = TREE_THIS_VOLATILE (decl);
*ws = 0;
}
else if (TREE_CODE (t) == CONSTRUCTOR)
;
else if (!EXPR_P (t))
*ws = 0;
return NULL_TREE;
}
/* Main entry point from the pass manager. */ /* Main entry point from the pass manager. */
@ -2043,9 +2066,9 @@ lto_output (void)
for (i = 0; i < n_nodes; i++) for (i = 0; i < n_nodes; i++)
{ {
symtab_node *snode = lto_symtab_encoder_deref (encoder, i); symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *node = dyn_cast <cgraph_node> (snode); if (cgraph_node *node = dyn_cast <cgraph_node> (snode))
if (node {
&& lto_symtab_encoder_encode_body_p (encoder, node) if (lto_symtab_encoder_encode_body_p (encoder, node)
&& !node->alias) && !node->alias)
{ {
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
@ -2063,6 +2086,15 @@ lto_output (void)
lto_record_function_out_decl_state (node->decl, decl_state); lto_record_function_out_decl_state (node->decl, decl_state);
} }
} }
else if (varpool_node *node = dyn_cast <varpool_node> (snode))
{
/* Wrap symbol references inside the ctor in a type
preserving MEM_REF. */
tree ctor = DECL_INITIAL (node->decl);
if (ctor && !in_lto_p)
walk_tree (&ctor, wrap_refs, NULL, NULL);
}
}
/* Emit the callgraph after emitting function bodies. This needs to /* Emit the callgraph after emitting function bodies. This needs to
be done now to make sure that all the statements in every function be done now to make sure that all the statements in every function

View File

@ -1,4 +1,10 @@
2014-01-20 Christian Bruel <christian.bruel@st.com> 2014-04-14 Richard Biener <rguenther@suse.de>
PR lto/60720
* gcc.dg/lto/pr60720_0.c: New testcase.
* gcc.dg/lto/pr60720_1.c: Likewise.
2014-04-14 Christian Bruel <christian.bruel@st.com>
* gcc.target/sh/memset.c: New test. * gcc.target/sh/memset.c: New test.

View File

@ -0,0 +1,15 @@
/* { dg-lto-do run } */
/* { dg-extra-ld-options { -w } } */
/* ??? lto.exp does not allow to scan for
:1:12: warning: type of 'x' does not match original declaration
extern int x[];
^
:1:5: note: previously declared here
int x;
^ */
extern int x[];
int *foo[] = { &x[0] };
int main() { return *foo[0]; }

View File

@ -0,0 +1 @@
int x;