This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]