lto/94822 - fix ICE in component_ref_size
authorRichard Biener <rguenther@suse.de>
Wed, 29 Apr 2020 10:21:23 +0000 (12:21 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 29 Apr 2020 10:25:16 +0000 (12:25 +0200)
This ICE appears because gcc will stream it to the function_body section
when processing the variable with the initial value of the constructor
type, and the error_mark_node to the decls section.
When recompiling, the value obtained with DECL_INITIAL will be error_mark.

2020-04-29  Richard Biener  <rguenther@suse.de>
    Li Zekun  <lizekun1@huawei.com>

PR lto/94822
* tree.c (component_ref_size): Guard against error_mark_node
DECL_INITIAL as it happens with LTO.

* gcc.dg/lto/pr94822_0.c: New testcase.
* gcc.dg/lto/pr94822_1.c: Alternate file.
* gcc.dg/lto/pr94822.h: Likewise.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/pr94822.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr94822_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr94822_1.c [new file with mode: 0644]
gcc/tree.c

index 3a352f8..4b4eeef 100644 (file)
@@ -1,3 +1,10 @@
+2020-04-29  Richard Biener  <rguenther@suse.de>
+           Li Zekun  <lizekun1@huawei.com>
+
+       PR lto/94822
+       * tree.c (component_ref_size): Guard against error_mark_node
+       DECL_INITIAL as it happens with LTO.
+
 2020-04-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_function_arg_alignment): Add a
index 701af0b..3810ea3 100644 (file)
@@ -1,3 +1,11 @@
+2020-04-29  Richard Biener  <rguenther@suse.de>
+           Li Zekun  <lizekun1@huawei.com>
+
+       PR lto/94822
+       * gcc.dg/lto/pr94822_0.c: New testcase.
+       * gcc.dg/lto/pr94822_1.c: Alternate file.
+       * gcc.dg/lto/pr94822.h: Likewise.
+
 2020-04-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * g++.target/aarch64/no_unique_address_1.C: New test.
diff --git a/gcc/testsuite/gcc.dg/lto/pr94822.h b/gcc/testsuite/gcc.dg/lto/pr94822.h
new file mode 100644 (file)
index 0000000..d9e6c3d
--- /dev/null
@@ -0,0 +1,4 @@
+typedef struct {
+  int i;
+  int ints[];
+} struct_t;
diff --git a/gcc/testsuite/gcc.dg/lto/pr94822_0.c b/gcc/testsuite/gcc.dg/lto/pr94822_0.c
new file mode 100644 (file)
index 0000000..698c092
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-lto-do link } */
+
+#include "pr94822.h"
+
+extern struct_t my_struct;
+
+int main() {
+ return my_struct.ints[1];
+}
+
diff --git a/gcc/testsuite/gcc.dg/lto/pr94822_1.c b/gcc/testsuite/gcc.dg/lto/pr94822_1.c
new file mode 100644 (file)
index 0000000..a7ace71
--- /dev/null
@@ -0,0 +1,6 @@
+#include "pr94822.h"
+
+struct_t my_struct = {
+ 20,
+ { 1, 2 }
+};
index e28b295..e451401 100644 (file)
@@ -13723,24 +13723,25 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
     /* MEMBER is a true flexible array member.  Compute its size from
        the initializer of the BASE object if it has one.  */
     if (tree init = DECL_P (base) ? DECL_INITIAL (base) : NULL_TREE)
-      {
-       init = get_initializer_for (init, member);
-       if (init)
-         {
-           memsize = TYPE_SIZE_UNIT (TREE_TYPE (init));
-           if (tree refsize = TYPE_SIZE_UNIT (reftype))
-             {
-               /* Use the larger of the initializer size and the tail
-                  padding in the enclosing struct.  */
-               poly_int64 rsz = tree_to_poly_int64 (refsize);
-               rsz -= baseoff;
-               if (known_lt (tree_to_poly_int64 (memsize), rsz))
-                 memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz);
-             }
+      if (init != error_mark_node)
+       {
+         init = get_initializer_for (init, member);
+         if (init)
+           {
+             memsize = TYPE_SIZE_UNIT (TREE_TYPE (init));
+             if (tree refsize = TYPE_SIZE_UNIT (reftype))
+               {
+                 /* Use the larger of the initializer size and the tail
+                    padding in the enclosing struct.  */
+                 poly_int64 rsz = tree_to_poly_int64 (refsize);
+                 rsz -= baseoff;
+                 if (known_lt (tree_to_poly_int64 (memsize), rsz))
+                   memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz);
+               }
 
-           baseoff = 0;
-         }
-      }
+             baseoff = 0;
+           }
+       }
 
   if (!memsize)
     {