[PATCH] Fix PR85244

Richard Biener rguenther@suse.de
Fri Apr 6 11:46:00 GMT 2018


The following fixes PR85244 where we fail to handle a flex-array
reference as such and constrain it with the appearant size of an external
declaration.  The fix is to handle this case much like the unconstrained
common one and to not regress some cases the patch adjusts the handling
of flex-array detection when visiting component references.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2018-04-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/85244
	* tree-dfa.c (get_ref_base_and_extent): Reset seen_variable_array_ref
	after seeing a component reference with an adjacent field.  Treat
	refs to arrays at struct end of external decls similar to
	refs to unconstrained commons.

	* gcc.dg/torture/pr85244-1.c: New testcase.
	* gcc.dg/torture/pr85244-2.c: Likewise.

Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c	(revision 259082)
+++ gcc/tree-dfa.c	(working copy)
@@ -438,7 +438,7 @@ get_ref_base_and_extent (tree exp, poly_
 		   referenced the last field of a struct or a union member
 		   then we have to adjust maxsize by the padding at the end
 		   of our field.  */
-		if (seen_variable_array_ref && known_size_p (maxsize))
+		if (seen_variable_array_ref)
 		  {
 		    tree stype = TREE_TYPE (TREE_OPERAND (exp, 0));
 		    tree next = DECL_CHAIN (field);
@@ -454,7 +454,7 @@ get_ref_base_and_extent (tree exp, poly_
 			    || ssize == NULL
 			    || !poly_int_tree_p (ssize))
 			  maxsize = -1;
-			else
+			else if (known_size_p (maxsize))
 			  {
 			    poly_offset_int tem
 			      = (wi::to_poly_offset (ssize)
@@ -464,6 +464,11 @@ get_ref_base_and_extent (tree exp, poly_
 			    maxsize += tem;
 			  }
 		      }
+		    /* An component ref with an adjacent field up in the
+		       structure hierarchy constrains the size of any variable
+		       array ref lower in the access hierarchy.  */
+		    else
+		      seen_variable_array_ref = false;
 		  }
 	      }
 	    else
@@ -622,7 +627,9 @@ get_ref_base_and_extent (tree exp, poly_
 
   if (DECL_P (exp))
     {
-      if (flag_unconstrained_commons && VAR_P (exp) && DECL_COMMON (exp))
+      if (VAR_P (exp)
+	  && ((flag_unconstrained_commons && DECL_COMMON (exp))
+	      || (DECL_EXTERNAL (exp) && seen_variable_array_ref)))
 	{
 	  tree sz_tree = TYPE_SIZE (TREE_TYPE (exp));
 	  /* If size is unknown, or we have read to the end, assume there
Index: gcc/testsuite/gcc.dg/torture/pr85244-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr85244-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr85244-1.c	(working copy)
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-sources "pr85244-2.c" } */
+
+struct s {
+ long a;
+ int b;
+ int tab[];
+};
+
+extern const struct s val;
+extern int idx;
+extern void abort (void);
+
+int main()
+{
+  if (val.tab[0] != 42 || val.tab[1] != 1337 || val.tab[idx] != 1337)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/torture/pr85244-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr85244-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr85244-2.c	(working copy)
@@ -0,0 +1,8 @@
+struct s {
+    long a;
+    int b;
+    int tab[];
+};
+
+int idx = 1;
+const struct s val = { 0, 0, { 42, 1337 } };



More information about the Gcc-patches mailing list