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>
* 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 ();
}
/* 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. */
@ -2043,24 +2066,33 @@ lto_output (void)
for (i = 0; i < n_nodes; i++)
{
symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *node = dyn_cast <cgraph_node> (snode);
if (node
&& lto_symtab_encoder_encode_body_p (encoder, node)
&& !node->alias)
if (cgraph_node *node = dyn_cast <cgraph_node> (snode))
{
if (lto_symtab_encoder_encode_body_p (encoder, node)
&& !node->alias)
{
#ifdef ENABLE_CHECKING
gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl)));
bitmap_set_bit (output, DECL_UID (node->decl));
gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl)));
bitmap_set_bit (output, DECL_UID (node->decl));
#endif
decl_state = lto_new_out_decl_state ();
lto_push_out_decl_state (decl_state);
if (gimple_has_body_p (node->decl) || !flag_wpa)
output_function (node);
else
copy_function (node);
gcc_assert (lto_get_out_decl_state () == decl_state);
lto_pop_out_decl_state ();
lto_record_function_out_decl_state (node->decl, decl_state);
decl_state = lto_new_out_decl_state ();
lto_push_out_decl_state (decl_state);
if (gimple_has_body_p (node->decl) || !flag_wpa)
output_function (node);
else
copy_function (node);
gcc_assert (lto_get_out_decl_state () == decl_state);
lto_pop_out_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);
}
}

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.

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;