From e6e616074f02b81c397a2848ab242b54ef21efbc Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 29 Apr 2020 12:21:23 +0200 Subject: [PATCH] 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 Li Zekun 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 | 7 ++++++ gcc/testsuite/ChangeLog | 8 +++++++ gcc/testsuite/gcc.dg/lto/pr94822.h | 4 ++++ gcc/testsuite/gcc.dg/lto/pr94822_0.c | 10 ++++++++ gcc/testsuite/gcc.dg/lto/pr94822_1.c | 6 +++++ gcc/tree.c | 35 ++++++++++++++-------------- 6 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr94822.h create mode 100644 gcc/testsuite/gcc.dg/lto/pr94822_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr94822_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a352f8bbd3..4b4eeefb675 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-04-29 Richard Biener + Li Zekun + + 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 * config/aarch64/aarch64.c (aarch64_function_arg_alignment): Add a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 701af0b1e72..3810ea3375e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-04-29 Richard Biener + Li Zekun + + 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 * 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 00000000000..d9e6c3da645 --- /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 00000000000..698c0928a81 --- /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 00000000000..a7ace71680f --- /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 e28b29580ca..e451401822c 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) { -- 2.30.2