diff mbox

[C] Enable initializing statics with COMPOUND_LITERAL_EXPR in C99 (PR c/63567)

Message ID 20141017205253.GV10501@redhat.com
State New
Headers show

Commit Message

Marek Polacek Oct. 17, 2014, 8:52 p.m. UTC
On Fri, Oct 17, 2014 at 03:53:46PM +0000, Joseph S. Myers wrote:
> On Fri, 17 Oct 2014, Marek Polacek wrote:
> 
> > Building Linux kernel failed with 'error: initializer element is not
> > constant', because they're initializing objects with static storage
> > duration with (T){ ...} - and that isn't permitted in gnu99/gnu11.
> > 
> > I think the Right Thing is to allow some latitude here and enable it
> > even in gnu99/gnu11 unless -pedantic.  In gnu89, this will work as
> > before even with -pedantic.
> 
> The Right Thing is for -pedantic not to cause errors, only warnings 
> (-pedantic-errors being needed for an error).  So rather than having this 
> conditional for whether to allow the extension at all, make the 
> conditional code do a pedwarn (if flag_isoc99, otherwise there will 
> already have been one for using a compound literal at all, and not for 

Thanks, I thought about this too.  So like the following?

> VECTOR_TYPE).  (I don't believe this can affect the semantics of valid 
> code; in this case of require_constant with a compound literal, we know 
> the code is invalid in ISO C terms, so it's safe to diagnose it then 
> interpret it in a sensible way.)

I agree.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-10-17  Marek Polacek  <polacek@redhat.com>

	PR c/63567
	* c-typeck.c (digest_init): Allow initializing objects with static
	storage duration with compound literals even in C99 and add pedwarn
	for it.

	* gcc.dg/pr61096-1.c: Change dg-error into dg-warning.
	* gcc.dg/pr63567-1.c: New test.
	* gcc.dg/pr63567-2.c: New test.


	Marek

Comments

Joseph Myers Oct. 17, 2014, 8:58 p.m. UTC | #1
On Fri, 17 Oct 2014, Marek Polacek wrote:

> Bootstrapped/regtested on x86_64-linux, ok for trunk?
> 
> 2014-10-17  Marek Polacek  <polacek@redhat.com>
> 
> 	PR c/63567
> 	* c-typeck.c (digest_init): Allow initializing objects with static
> 	storage duration with compound literals even in C99 and add pedwarn
> 	for it.
> 
> 	* gcc.dg/pr61096-1.c: Change dg-error into dg-warning.
> 	* gcc.dg/pr63567-1.c: New test.
> 	* gcc.dg/pr63567-2.c: New test.

OK.
diff mbox

Patch

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 324736a..0dd3366 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -6683,13 +6683,15 @@  digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	inside_init = convert (type, inside_init);
 
       if (require_constant
-	  && (code == VECTOR_TYPE || !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).  Also allow this for
 	     vectors, as we can only assign them with compound literals.  */
+	  if (flag_isoc99 && code != VECTOR_TYPE)
+	    pedwarn_init (init_loc, OPT_Wpedantic, "initializer element "
+			  "is not constant");
 	  tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
 	  inside_init = DECL_INITIAL (decl);
 	}
diff --git gcc/testsuite/gcc.dg/pr61096-1.c gcc/testsuite/gcc.dg/pr61096-1.c
index 3f7d60c..fa8932f 100644
--- gcc/testsuite/gcc.dg/pr61096-1.c
+++ gcc/testsuite/gcc.dg/pr61096-1.c
@@ -23,7 +23,7 @@  char w1[] = L"foo"; /* { dg-error "13:char-array initialized from wide string" }
 __WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:wide character array initialized from non-wide string" } */
 __WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */
 schar a1[] = "foo"; /* { dg-error "14:array of inappropriate type initialized from string constant" } */
-int a2[] = (int[]) { 1 }; /* { dg-error "12:array initialized from non-constant array expression" } */
+int a2[] = (int[]) { 1 }; /* { dg-warning "12:initializer element is not constant" } */
 
 int a3 = e; /* { dg-error "10:initializer element is not constant" } */
 int a4 = (e, 1); /* { dg-error "10:initializer element is not constant" } */
diff --git gcc/testsuite/gcc.dg/pr63567-1.c gcc/testsuite/gcc.dg/pr63567-1.c
index e69de29..97da171 100644
--- gcc/testsuite/gcc.dg/pr63567-1.c
+++ gcc/testsuite/gcc.dg/pr63567-1.c
@@ -0,0 +1,10 @@ 
+/* PR c/63567 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Allow initializing objects with static storage duration with
+   compound literals even.  This is being used in Linux kernel.  */
+
+struct T { int i; };
+struct S { struct T t; };
+static struct S s = (struct S) { .t = { 42 } };
diff --git gcc/testsuite/gcc.dg/pr63567-2.c gcc/testsuite/gcc.dg/pr63567-2.c
index e69de29..5ea2b37 100644
--- gcc/testsuite/gcc.dg/pr63567-2.c
+++ gcc/testsuite/gcc.dg/pr63567-2.c
@@ -0,0 +1,10 @@ 
+/* PR c/63567 */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+/* Allow initializing objects with static storage duration with
+   compound literals.  This is being used in Linux kernel.  */
+
+struct T { int i; };
+struct S { struct T t; };
+static struct S s = (struct S) { .t = { 42 } }; /* { dg-warning "initializer element is not constant" } */