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:
parent
3af37d3f59
commit
59c83dbf28
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
37
gcc/testsuite/gcc.dg/gnu89-init-1.c
Normal file
37
gcc/testsuite/gcc.dg/gnu89-init-1.c
Normal 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user