diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-12-12 19:12:16 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-12-12 19:12:16 +0000 |
commit | 4619fc1556ec08218e75d70eb64d0eaad1e356e1 (patch) | |
tree | 52579c466b178af3b34b3b7f1c35b83542ee7516 | |
parent | 183b00a053d0b3b1b7faea6f4d629fc870ed13a4 (diff) | |
download | gcc-4619fc1556ec08218e75d70eb64d0eaad1e356e1.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47945 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-typeck.c | 15 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gnu89-init-1.c | 37 |
5 files changed, 84 insertions, 2 deletions
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 <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 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 <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. 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 <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); +} |