This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Support initialization by compound literal in designated initializers (take 2)
On Wed, Jan 02, 2002 at 06:52:08PM +0000, Joseph S. Myers wrote:
Guess I'll split the patch into 4 patchlets, so that they can be discussed
separately. Attached below is the actual fix for Linux kernel alone.
> On Wed, 2 Jan 2002, Jakub Jelinek wrote:
>
> > c) puts const qualified compound literals into const section and not data
> > section (and in some limited cases merge them, though more code would be
> > needed to merge them for any complit size)
> Isn't this a new feature rather than a bug / regression / Linux kernel
> compilation fix?
Well, I'll split the above into 2 patches, one just the TREE_CONSTANT
setting and the other one for merging.
> I'd like to see a testcase for this merging. If it depends on assembler /
> linker features then the tests should return UNSUPPORTED on systems
> without the necessary features.
I'll try to cook something up using 2 object files and seeing if simple
string literal was merged, if yes, doing the test.
> > - a unique suffix to be added to the name, for which DECL_CONTEXT
> > - must be set. */
> > - DECL_NAME (decl) = get_identifier ("__compound_literal");
> > - DECL_CONTEXT (decl) = complit;
> > + a unique suffix to be added to the name. */
> > + char *name;
> > + static int compound_literal_labelno;
> > +
> > + ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
> > + compound_literal_labelno);
> > + compound_literal_labelno++;
> > + DECL_NAME (decl) = get_identifier (name);
> > + DECL_DEFER_OUTPUT (decl) = 1;
> > rest_of_decl_compilation (decl, NULL, 1, 0);
> > - DECL_CONTEXT (decl) = NULL_TREE;
> > + defer_complit (decl);
>
> Will this break if the user defines static __compound_literal variables?
User can define __compound_literal.26 as variable?
There are a few systems which use ___, ?, %, $ or nothing as separator
instead, but do we issue errors for say:
int i___0;
static int foo () { static int i; return i++; }
on VMS or:
int i0;
static int foo () { static int i; return i++; }
on i370?
> If so, we should give an error when they try to define such variables
> rather than leaving it to a later assembler error.
>
> Do compound literals in dead code (or within sizeof) still get emitted?
Dead code would mean automatic compound literal, which is not emitted.
But if you mean:
static const int *p = 1 ? (const int *) 0 : & (const int) { 26 };
int q = sizeof ((int [6]) { 1, 2, 3, 4, 5, 6 }) + 4;
they are still emitted.
To make them not emitted, I think we'd need to add a language hook into
wrapup_global_declarations, because:
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& (((! TREE_READONLY (decl) || TREE_PUBLIC (decl))
&& !DECL_COMDAT (decl))
|| (!optimize
&& flag_keep_static_consts
&& !DECL_ARTIFICIAL (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
would emit all non-const qualified compound literals even if they are not
referenced from anywhere (and similarly at -O0 all compound literals).
Another option, which could work, would be to abuse DECL_COMDAT here (which
is never used by C frontend nor backend as far as I can see, just in the
above if; setting it to 1 would mean only the referenced check would be
active in -O1+).
What do you think?
Ok to commit following?
2002-01-02 Jakub Jelinek <jakub@redhat.com>
* c-typeck.c (output_init_element): Allow initializing static storage
duration objects with compound literals.
* gcc.dg/gnu89-init-1.c: Added new tests.
--- gcc/c-typeck.c.jj Mon Dec 31 11:52:13 2001
+++ gcc/c-typeck.c Thu Jan 3 00:00:01 2002
@@ -6275,6 +6275,16 @@ output_init_element (value, type, field,
TYPE_MAIN_VARIANT (type))))
value = default_conversion (value);
+ if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
+ && require_constant_value && !flag_isoc99 && pending)
+ {
+ /* 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 (value);
+ value = DECL_INITIAL (decl);
+ }
+
if (value == error_mark_node)
constructor_erroneous = 1;
else if (!TREE_CONSTANT (value))
--- gcc/testsuite/gcc.dg/gnu89-init-1.c.jj Thu Dec 27 16:54:41 2001
+++ gcc/testsuite/gcc.dg/gnu89-init-1.c Wed Jan 2 16:46:12 2002
@@ -8,6 +8,8 @@ extern void exit (int);
struct A { int i; int j; int k[4]; };
struct B { };
+struct C { int i; };
+struct D { int i; struct C j; };
/* As a GNU extension, we allow initialization of objects with static storage
duration by compound literals. It is handled as if the object
@@ -22,6 +24,10 @@ int c[] = (int []) { [2] = 6, 7, 8 };
int d[] = (int [3]) { 1 };
int e[2] = (int []) { 1, 2 };
int f[2] = (int [2]) { 1 };
+struct C g[3] = { [2] = (struct C) { 13 }, [1] = (const struct C) { 12 } };
+struct D h = { .j = (struct C) { 15 }, .i = 14 };
+struct D i[2] = { [1].j = (const struct C) { 17 },
+ [0] = { 0, (struct C) { 16 } } };
int main (void)
{
@@ -43,5 +49,11 @@ int main (void)
abort ();
if (sizeof (f) != 2 * sizeof (int))
abort ();
+ if (g[0].i || g[1].i != 12 || g[2].i != 13)
+ abort ();
+ if (h.i != 14 || h.j.i != 15)
+ abort ();
+ if (i[0].i || i[0].j.i != 16 || i[1].i || i[1].j.i != 17)
+ abort ();
exit (0);
}
Jakub