diff options
author | Richard Biener <rguenth@gcc.gnu.org> | 2014-04-14 08:35:22 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-04-14 08:35:22 +0000 |
commit | 8359c87e12157ec6a75026f2f90a7e032a3de30c (patch) | |
tree | 206513ad080c96ac3a9e1f365f8c2a44e3ff71f1 /gcc | |
parent | 9447df74c059415f2c53df95d845ab9964793074 (diff) | |
download | gcc-8359c87e12157ec6a75026f2f90a7e032a3de30c.zip gcc-8359c87e12157ec6a75026f2f90a7e032a3de30c.tar.gz gcc-8359c87e12157ec6a75026f2f90a7e032a3de30c.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 62 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/pr60720_0.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/pr60720_1.c | 1 |
5 files changed, 77 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d1bc3d..0267359 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 69b5a79..b193d73 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -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); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b85529..6c49b9a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.dg/lto/pr60720_0.c b/gcc/testsuite/gcc.dg/lto/pr60720_0.c new file mode 100644 index 0000000..79cef5d --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60720_0.c @@ -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]; } diff --git a/gcc/testsuite/gcc.dg/lto/pr60720_1.c b/gcc/testsuite/gcc.dg/lto/pr60720_1.c new file mode 100644 index 0000000..6d1a0d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60720_1.c @@ -0,0 +1 @@ +int x; |