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>
|
2001-12-12 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* emit-rtl.c (adjust_address_1): Always copy address to avoid
|
* 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)
|
if (code == POINTER_TYPE)
|
||||||
inside_init = default_function_array_conversion (inside_init);
|
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");
|
error_init ("array initialized from non-constant array expression");
|
||||||
return error_mark_node;
|
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
|
also allowed, but then the compound literal is equivalent
|
||||||
to a cast.
|
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
|
@node Designated Inits
|
||||||
@section Designated Initializers
|
@section Designated Initializers
|
||||||
@cindex initializers with labeled elements
|
@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>
|
2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
* g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename.
|
* g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename.
|
||||||
|
|
|
@ -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…
Reference in New Issue