diff mbox series

lto/94822 - fix ICE in component_ref_size

Message ID nycvar.YFH.7.76.2004291225430.4397@zhemvz.fhfr.qr
State New
Headers show
Series lto/94822 - fix ICE in component_ref_size | expand

Commit Message

Richard Biener April 29, 2020, 10:26 a.m. UTC
Bootstrapped/tested on x86_64-unknown-linux-gnu, pushed.

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/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 ++++++++++++++--------------
 4 files changed, 38 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 mbox series

Patch

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)
     {