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  <pola...@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.

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" } */

        Marek

Reply via email to