From 59c83dbf283e0dcf89ecfcfcbab856682291842a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 Dec 2001 20:12:16 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++++ gcc/c-typeck.c | 15 ++++++++++-- gcc/doc/extend.texi | 24 +++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/gnu89-init-1.c | 37 +++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/gnu89-init-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed8c11b95fe..acd75f9769e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2001-12-12 Jakub Jelinek + + * 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 * emit-rtl.c (adjust_address_1): Always copy address to avoid diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 56775049a1c..f3f7d096964 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 80addd33160..9b97805f151 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 534af00eea3..489171423d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-12-12 Jakub Jelinek + + * gcc.dg/gnu89-init-1.c: New test. + 2001-12-12 Nathan Sidwell * g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename. diff --git a/gcc/testsuite/gcc.dg/gnu89-init-1.c b/gcc/testsuite/gcc.dg/gnu89-init-1.c new file mode 100644 index 00000000000..dae61b57da5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu89-init-1.c @@ -0,0 +1,37 @@ +/* Test for GNU extensions to compound literals */ +/* Origin: Jakub Jelinek */ +/* { 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); +}