re PR lto/60720 (clisp fails to build with -flto: internal compiler error: tree check...
authorRichard Biener <rguenth@gcc.gnu.org>
Mon, 14 Apr 2014 08:35:22 +0000 (08:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 14 Apr 2014 08:35:22 +0000 (08:35 +0000)
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

gcc/ChangeLog
gcc/lto-streamer-out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/pr60720_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr60720_1.c [new file with mode: 0644]

index 4d1bc3d58cce3f13bcfe3bb7ea66a93e1062d8ba..026735907fd97da54f0f32f0bf94c8b15bc9092e 100644 (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.
index 69b5a79e5395eedd2e582101606a92bed4315bb3..b193d730d75b9c4a7de9b625f1565208f6d6a88f 100644 (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);
        }
     }
 
index 3b85529b8fcb399477b69e4040c7f27bfb7d0ef5..6c49b9aa5890684c53b8620e38f10e73c28a7ea6 100644 (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.
 
diff --git a/gcc/testsuite/gcc.dg/lto/pr60720_0.c b/gcc/testsuite/gcc.dg/lto/pr60720_0.c
new file mode 100644 (file)
index 0000000..79cef5d
--- /dev/null
@@ -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 (file)
index 0000000..6d1a0d4
--- /dev/null
@@ -0,0 +1 @@
+int x;