This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][LTO] Fix PR60720
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <hubicka at ucw dot cz>
- Date: Tue, 1 Apr 2014 13:06:16 +0200 (CEST)
- Subject: Re: [PATCH][LTO] Fix PR60720
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1403311522561 dot 31108 at zhemvz dot fhfr dot qr>
On Mon, 31 Mar 2014, Richard Biener wrote:
>
> The following patch makes sure we wrap symbol references in global
> initializers the same as we do for IL references - inside a MEM_REF
> that guards their context against type changes due to symbol merging
> (and thus in this case against ICEs when processing an ARRAY_REF
> around a non-array object).
>
> LTO bootstrap & regtest running on x86_64-unknown-linux-gnu.
It turns out that changing the tree structure while doing a DFS
walk is a bad idea so the following patch instead does it at
lto_output time (and restricts it to necessary cases,
handled-component-refs wrapping the decls).
LTO bootstrapped and tested on x86_64-unknown-linux-gnu, queued for
stage1.
Richard.
2014-04-01 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.
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c (revision 208955)
--- gcc/lto-streamer-out.c (working copy)
*************** copy_function (struct cgraph_node *node)
*** 2024,2029 ****
--- 2024,2052 ----
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. */
*************** lto_output (void)
*** 2045,2068 ****
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)
{
#ifdef ENABLE_CHECKING
! 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);
}
}
--- 2068,2100 ----
for (i = 0; i < n_nodes; i++)
{
symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
! 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));
#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);
! }
! }
! 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);
}
}
Index: gcc/testsuite/gcc.dg/lto/pr60720_0.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/pr60720_0.c (revision 0)
--- gcc/testsuite/gcc.dg/lto/pr60720_0.c (working copy)
***************
*** 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]; }
Index: gcc/testsuite/gcc.dg/lto/pr60720_1.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/pr60720_1.c (revision 0)
--- gcc/testsuite/gcc.dg/lto/pr60720_1.c (working copy)
***************
*** 0 ****
--- 1 ----
+ int x;