diff options
author | Richard Biener <rguenther@suse.de> | 2020-04-29 12:21:23 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-04-29 12:25:16 +0200 |
commit | e6e616074f02b81c397a2848ab242b54ef21efbc (patch) | |
tree | b8ad7a4f51ce18f0ca707802a74a6575c404dd56 /gcc/tree.c | |
parent | 56fe3ca30e1343e4f232ca539726506440e23dd3 (diff) | |
download | gcc-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/tree.c')
-rw-r--r-- | gcc/tree.c | 35 |
1 files changed, 18 insertions, 17 deletions
@@ -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) { |