[PATCH] gimplification of types (PR c/21536) (take 2)

Jakub Jelinek jakub@redhat.com
Sat May 28 13:49:00 GMT 2005


On Fri, May 27, 2005 at 01:16:45PM -0700, Richard Henderson wrote:
> On Fri, May 27, 2005 at 01:58:07PM -0400, Jakub Jelinek wrote:
> > ... or the frontends would need to guarantee that for all types with some
> > variable TYPE_SIZE reachable from the type there would be a DECL_EXPR with
> > TYPE_DECL right before the first use of such type.
> > What's your preference?
> 
> This later option should be the eventual goal.  That's not appropriate
> for the 4.0 branch though.  Your posted patch plus some additions for
> aggregates should be good enough for that.

Here is what I have bootstrapped on 4.0 branch on i386-linux.
Ok for 4.0?
What about HEAD, can I apply it there as well and file a HEAD PR about
missing DECL_EXPRs with TYPE_DECLs?

2005-05-28  Jakub Jelinek  <jakub@redhat.com>

	PR c/21536
	PR c/20760
	* gimplify.c (gimplify_decl_expr): Call gimplify_type_sizes
	on variable sizes types if a decl is a pointer to a VLA.
	(gimplify_type_sizes): Handle POINTER_TYPE and REFERENCE_TYPE.
	Call gimplify_type_sizes on aggregate fields.  Prevent infinite
	recursion.

	* gcc.dg/20050527-1.c: New test.

--- gcc/gimplify.c.jj	2005-05-06 09:58:27.000000000 +0200
+++ gcc/gimplify.c	2005-05-28 11:06:19.000000000 +0200
@@ -983,10 +983,12 @@ gimplify_decl_expr (tree *stmt_p)
   if (TREE_TYPE (decl) == error_mark_node)
     return GS_ERROR;
 
-  else if (TREE_CODE (decl) == TYPE_DECL)
+  if ((TREE_CODE (decl) == TYPE_DECL
+       || TREE_CODE (decl) == VAR_DECL)
+      && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
     gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
 
-  else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
       tree init = DECL_INITIAL (decl);
 
@@ -997,12 +999,6 @@ gimplify_decl_expr (tree *stmt_p)
 	     of the emitted code: see mx_register_decls().  */
 	  tree t, args, addr, ptr_type;
 
-	  /* ??? We really shouldn't need to gimplify the type of the variable
-	     since it already should have been done.  But leave this here
-	     for now to avoid disrupting too many things at once.  */
-	  if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
-	    gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
-
 	  gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
 	  gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
 
@@ -4360,21 +4356,21 @@ gimplify_type_sizes (tree type, tree *li
 {
   tree field, t;
 
-  /* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because
-     that's not supposed to happen on types where gimplification does anything.
-     We should assert that it isn't set, but we can indeed be called multiple
-     times on pointers.  Unfortunately, this includes fat pointers which we
-     can't easily test for.  We could pass TYPE down to gimplify_one_sizepos
-     and test there, but it doesn't seem worth it.  */
+  if (type == NULL)
+    return;
 
   /* We first do the main variant, then copy into any other variants. */
   type = TYPE_MAIN_VARIANT (type);
 
+  /* Avoid infinite recursion.  */
+  if (TYPE_SIZES_GIMPLIFIED (type)
+      || type == error_mark_node)
+    return;
+
+  TYPE_SIZES_GIMPLIFIED (type) = 1;
+
   switch (TREE_CODE (type))
     {
-    case ERROR_MARK:
-      return;
-
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
@@ -4387,17 +4383,13 @@ gimplify_type_sizes (tree type, tree *li
 	{
 	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
 	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
-	  TYPE_SIZES_GIMPLIFIED (t) = 1;
 	}
       break;
 
     case ARRAY_TYPE:
       /* These types may not have declarations, so handle them here.  */
-      if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type)))
-	gimplify_type_sizes (TREE_TYPE (type), list_p);
-
-      if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type)))
-	  gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
+      gimplify_type_sizes (TREE_TYPE (type), list_p);
+      gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
       break;
 
     case RECORD_TYPE:
@@ -4405,7 +4397,15 @@ gimplify_type_sizes (tree type, tree *li
     case QUAL_UNION_TYPE:
       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
 	if (TREE_CODE (field) == FIELD_DECL)
-	  gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
+	  {
+	    gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
+	    gimplify_type_sizes (TREE_TYPE (field), list_p);
+	  }
+      break;
+
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+      gimplify_type_sizes (TREE_TYPE (type), list_p);
       break;
 
     default:
@@ -4421,8 +4421,6 @@ gimplify_type_sizes (tree type, tree *li
       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
       TYPE_SIZES_GIMPLIFIED (t) = 1;
     }
-
-  TYPE_SIZES_GIMPLIFIED (type) = 1;
 }
 
 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
--- gcc/testsuite/gcc.dg/20050527-1.c.jj	2005-05-27 19:22:32.000000000 +0200
+++ gcc/testsuite/gcc.dg/20050527-1.c	2005-05-27 22:43:45.000000000 +0200
@@ -0,0 +1,55 @@
+/* PR c/21536 */
+/* { dg-do run } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *malloc (size_t);
+extern void free (void *);
+
+void *
+foo (int x, int y)
+{
+  void *d = malloc (x * y * sizeof (double));
+  double (*e)[x][y] = d;
+  x += 10;
+  y += 10;
+  if (x > 18)
+    (*e)[x - 12][y - 12] = 0.0;
+  else
+    (*e)[x - 11][y - 11] = 1.0;
+  return d;
+}
+
+void *
+bar (int x, int y)
+{
+  void *d = malloc (x * y * sizeof (double));
+  struct S
+    {
+      double (*e)[x][y];
+      double (*f)[x][y];
+    } s;
+  s.e = d;
+  s.f = d;
+  x += 10;
+  y += 10;
+  if (x > 18)
+    (*s.e)[x - 12][y - 12] = 0.0;
+  else
+    (*s.e)[x - 11][y - 11] = 1.0;
+  if (x > 16)
+    (*s.f)[x - 13][y - 13] = 0.0;
+  else
+    (*s.f)[x - 14][y - 14] = 1.0;
+  return d;
+}
+
+int
+main ()
+{
+  void *d1 = foo (10, 10);
+  void *d2 = bar (10, 10);
+  free (d1);
+  free (d2);
+  return 0;
+}


	Jakub



More information about the Gcc-patches mailing list