[PATCH] Fix initialization by compound literal (was Re: [PATCH] Allow compound literals in static storage duration object initializers)

Jakub Jelinek jakub@redhat.com
Thu Dec 27 09:50:00 GMT 2001


On Wed, Dec 12, 2001 at 12:46:31PM -0800, Richard Henderson wrote:
> On Wed, Dec 12, 2001 at 07:00:06PM +0000, Joseph S. Myers wrote:
> > > a) handle it the same way as older gcc, which is kind of surprising
> > >    behaviour (this done in patch below)
> > > b) issue an error if compound literal's array type is not unknown
> > >    size and the size is different to the size of bracket enclosed
> > >    list
> > > c) handle it so that object gets size of the compound literal array type
> > 
> > If this extension were intentionally designed, clearly (c) would be 
> > appropriate; as it is, as an allowance for old code, (a), though 
> > surprising and of an odd design, may be best.
> 
> I don't think old code would have a problem with C.  I think you'll
> find that old code primarily uses this extension with structures.

Here is c) implementation (bootstrapped on i686-redhat-linux, no
regressions).
Ok to commit?

2001-12-27  Jakub Jelinek  <jakub@redhat.com>

	* c-typeck.c (store_init_value): If initializing object with array
	type of unknown size by a compound literal, set object's size from
	compound literal size.
	* doc/extend.texi (Compound Literals): Adjust documentation.

	* gnu89-init-1.c: Adjust for the new behaviour, add some additional
	tests.

--- gcc/c-typeck.c.jj	Thu Dec 27 13:49:10 2001
+++ gcc/c-typeck.c	Thu Dec 27 16:49:43 2001
@@ -4495,6 +4495,33 @@ store_init_value (decl, init)
   /* ANSI wants warnings about out-of-range constant initializers.  */
   STRIP_TYPE_NOPS (value);
   constant_expression_warning (value);
+
+  /* Check if we need to set array size from compound literal size.  */
+  if (TREE_CODE (type) == ARRAY_TYPE
+      && TYPE_DOMAIN (type) == 0
+      && value != error_mark_node)
+    {
+      tree inside_init = init;
+
+      if (TREE_CODE (init) == NON_LVALUE_EXPR)
+	inside_init = TREE_OPERAND (init, 0);
+      inside_init = fold (inside_init);
+
+      if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
+	{
+	  tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
+
+	  if (TYPE_DOMAIN (TREE_TYPE (decl)))
+	    {
+	      /* For int foo[] = (int [3]){1}; we need to set array size
+		 now since later on array initializer will be just the
+		 brace enclosed list of the compound literal.  */
+	      TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl));
+	      layout_type (type);
+	      layout_decl (decl, 0);
+	    }
+	}
+    }
 }
 
 /* Methods for storing and printing names for error messages.  */
--- gcc/doc/extend.texi.jj	Fri Dec 21 18:01:51 2001
+++ gcc/doc/extend.texi	Thu Dec 27 16:59:12 2001
@@ -1598,8 +1598,7 @@ It is handled as if the object was initi
 enclosed list if compound literal's and object types match.
 The initializer list of the compound literal must be constant.
 If the object being initialized has array type of unknown size, the size is
-determined by compound literal's initializer list, not by the size of the
-compound literal.
+determined by compound literal size.
 
 @example
 static struct foo x = (struct foo) @{1, 'a', 'b'@};
@@ -1612,7 +1611,7 @@ The above lines are equivalent to the fo
 @example
 static struct foo x = @{1, 'a', 'b'@};
 static int y[] = @{1, 2, 3@};
-static int z[] = @{1@};
+static int z[] = @{1, 0, 0@};
 @end example
 
 @node Designated Inits
--- gcc/testsuite/gcc.dg/gnu89-init-1.c.jj	Wed Dec 12 21:26:47 2001
+++ gcc/testsuite/gcc.dg/gnu89-init-1.c	Thu Dec 27 16:54:41 2001
@@ -20,6 +20,8 @@ struct A a = (struct A) { .j = 6, .k[2] 
 struct B b = (struct B) { };
 int c[] = (int []) { [2] = 6, 7, 8 };
 int d[] = (int [3]) { 1 };
+int e[2] = (int []) { 1, 2 };
+int f[2] = (int [2]) { 1 };
 
 int main (void)
 {
@@ -29,9 +31,17 @@ int main (void)
     abort ();
   if (sizeof (c) != 5 * sizeof (int))
     abort ();
-  if (d[0] != 1)
+  if (d[0] != 1 || d[1] || d[2])
     abort ();
-  if (sizeof (d) != sizeof (int))
+  if (sizeof (d) != 3 * sizeof (int))
+    abort ();
+  if (e[0] != 1 || e[1] != 2)
+    abort ();
+  if (sizeof (e) != 2 * sizeof (int))
+    abort ();
+  if (f[0] != 1 || f[1])
+    abort ();
+  if (sizeof (f) != 2 * sizeof (int))
     abort ();
   exit (0);
 }


	Jakub



More information about the Gcc-patches mailing list