c-typeck.c (digest_init): Allow initializing static storage duration objects with compound literals.

* c-typeck.c (digest_init): Allow initializing
	static storage duration objects with compound literals.
	* doc/extend.texi (Compound literals): Document the extension.

	* gcc.dg/gnu89-init-1.c: New test.

From-SVN: r47945
This commit is contained in:
Jakub Jelinek 2001-12-12 20:12:16 +01:00 committed by Jakub Jelinek
parent 3af37d3f59
commit 59c83dbf28
5 changed files with 84 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2001-12-12 Jakub Jelinek <jakub@redhat.com>
* c-typeck.c (digest_init): Allow initializing
static storage duration objects with compound literals.
* doc/extend.texi (Compound literals): Document the extension.
2001-12-12 Richard Henderson <rth@redhat.com>
* emit-rtl.c (adjust_address_1): Always copy address to avoid

View File

@ -4780,8 +4780,19 @@ digest_init (type, init, require_constant, constructor_constant)
{
if (code == POINTER_TYPE)
inside_init = default_function_array_conversion (inside_init);
else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
&& TREE_CODE (inside_init) != CONSTRUCTOR)
if (require_constant && !flag_isoc99
&& TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
{
/* As an extension, allow initializing objects with static storage
duration with compound literals (which are then treated just as
the brace enclosed list they contain). */
tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
inside_init = DECL_INITIAL (decl);
}
if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
&& TREE_CODE (inside_init) != CONSTRUCTOR)
{
error_init ("array initialized from non-constant array expression");
return error_mark_node;

View File

@ -1649,6 +1649,30 @@ Compound literals for scalar types and union types are is
also allowed, but then the compound literal is equivalent
to a cast.
As a GNU extension, GCC allows initialization of objects with static storage
duration by compound literals (which is not possible in ISO C99, because
the initializer is not a constant).
It is handled as if the object was initialized only with the bracket
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.
@example
static struct foo x = (struct foo) @{1, 'a', 'b'@};
static int y[] = (int []) @{1, 2, 3@};
static int z[] = (int [3]) @{1@};
@end example
@noindent
The above lines are equivalent to the following:
@example
static struct foo x = @{1, 'a', 'b'@};
static int y[] = @{1, 2, 3@};
static int z[] = @{1@};
@end example
@node Designated Inits
@section Designated Initializers
@cindex initializers with labeled elements

View File

@ -1,3 +1,7 @@
2001-12-12 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/gnu89-init-1.c: New test.
2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename.

View File

@ -0,0 +1,37 @@
/* Test for GNU extensions to compound literals */
/* Origin: Jakub Jelinek <jakub@redhat.com> */
/* { dg-do run } */
/* { dg-options "-std=gnu89" } */
extern void abort (void);
extern void exit (int);
struct A { int i; int j; int k[4]; };
struct B { };
/* As a GNU extension, we allow initialization of objects with static storage
duration by compound literals. It is handled as if the object
was initialized only with the bracket enclosed list if compound literal's
and object types match. If the object being initialized has array type
of unknown size, the size is determined by compound literal's initializer
list, not by size of the compound literal. */
struct A a = (struct A) { .j = 6, .k[2] = 12 };
struct B b = (struct B) { };
int c[] = (int []) { [2] = 6, 7, 8 };
int d[] = (int [3]) { 1 };
int main (void)
{
if (a.i || a.j != 6 || a.k[0] || a.k[1] || a.k[2] != 12 || a.k[3])
abort ();
if (c[0] || c[1] || c[2] != 6 || c[3] != 7 || c[4] != 8)
abort ();
if (sizeof (c) != 5 * sizeof (int))
abort ();
if (d[0] != 1)
abort ();
if (sizeof (d) != sizeof (int))
abort ();
exit (0);
}