This fixes PR55525, when with LTO you have mismatching types
for decls we ICE when we have an ARRAY_REF of sth that is not
an array.

Fixup, similar as for component-refs.

LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-12-05  Richard Biener  <rguent...@suse.de>

        PR lto/55525
        * gimple-streamer-in.c (input_gimple_stmt): Fixup ARRAY_REFs as well.

        * gcc.dg/lto/pr55525_0.c: New testcase.
        * gcc.dg/lto/pr55525_1.c: Likewise.

Index: gcc/gimple-streamer-in.c
===================================================================
*** gcc/gimple-streamer-in.c    (revision 194141)
--- gcc/gimple-streamer-in.c    (working copy)
*************** input_gimple_stmt (struct lto_input_bloc
*** 148,161 ****
          if (!op)
            continue;
  
-         /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
-            by decl merging.  */
          if (TREE_CODE (op) == ADDR_EXPR)
            op = TREE_OPERAND (op, 0);
          while (handled_component_p (op))
            {
              if (TREE_CODE (op) == COMPONENT_REF)
                {
                  tree field, type, tem;
                  tree closest_match = NULL_TREE;
                  field = TREE_OPERAND (op, 1);
--- 148,161 ----
          if (!op)
            continue;
  
          if (TREE_CODE (op) == ADDR_EXPR)
            op = TREE_OPERAND (op, 0);
          while (handled_component_p (op))
            {
              if (TREE_CODE (op) == COMPONENT_REF)
                {
+                 /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
+                    by decl merging.  */
                  tree field, type, tem;
                  tree closest_match = NULL_TREE;
                  field = TREE_OPERAND (op, 1);
*************** input_gimple_stmt (struct lto_input_bloc
*** 215,220 ****
--- 215,232 ----
                  else
                    TREE_OPERAND (op, 1) = tem;
                }
+             else if ((TREE_CODE (op) == ARRAY_REF
+                       || TREE_CODE (op) == ARRAY_RANGE_REF)
+                      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0)))
+                          != ARRAY_TYPE))
+               {
+                 /* And ARRAY_REFs to objects that had mismatched types
+                    during symbol merging to avoid ICEs.  */
+                 TREE_OPERAND (op, 0)
+                   = build1 (VIEW_CONVERT_EXPR,
+                             build_array_type (TREE_TYPE (op), NULL_TREE),
+                             TREE_OPERAND (op, 0));
+               }
  
              op = TREE_OPERAND (op, 0);
            }
Index: gcc/testsuite/gcc.dg/lto/pr55525_0.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/pr55525_0.c        (revision 0)
--- gcc/testsuite/gcc.dg/lto/pr55525_0.c        (working copy)
***************
*** 0 ****
--- 1,8 ----
+ /* { dg-lto-do link } */
+ /* { dg-lto-options { { -flto -w } } } */
+ 
+ char s[8];
+ int main(void)
+ {
+   return strcmp(&s[1], "foo");
+ }
Index: gcc/testsuite/gcc.dg/lto/pr55525_1.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/pr55525_1.c        (revision 0)
--- gcc/testsuite/gcc.dg/lto/pr55525_1.c        (working copy)
***************
*** 0 ****
--- 1 ----
+ char *s = (char *) 0;

Reply via email to