aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-04-29 12:21:23 +0200
committerRichard Biener <rguenther@suse.de>2020-04-29 12:25:16 +0200
commite6e616074f02b81c397a2848ab242b54ef21efbc (patch)
treeb8ad7a4f51ce18f0ca707802a74a6575c404dd56 /gcc
parent56fe3ca30e1343e4f232ca539726506440e23dd3 (diff)
downloadgcc-e6e616074f02b81c397a2848ab242b54ef21efbc.zip
gcc-e6e616074f02b81c397a2848ab242b54ef21efbc.tar.gz
gcc-e6e616074f02b81c397a2848ab242b54ef21efbc.tar.bz2
lto/94822 - fix ICE in component_ref_size
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr94822.h4
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr94822_0.c10
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr94822_1.c6
-rw-r--r--gcc/tree.c35
6 files changed, 53 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a352f8..4b4eeef 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 701af0b..3810ea3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d9e6c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr94822.h
@@ -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
index 0000000..698c092
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr94822_0.c
@@ -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
index 0000000..a7ace71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr94822_1.c
@@ -0,0 +1,6 @@
+#include "pr94822.h"
+
+struct_t my_struct = {
+ 20,
+ { 1, 2 }
+};
diff --git a/gcc/tree.c b/gcc/tree.c
index e28b295..e451401 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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)
{