================
@@ -1,13 +1,158 @@
-// RUN: %clang_cc1 %s -verify=c -fsyntax-only
-// RUN: %clang_cc1 %s -verify -fsyntax-only -x c++
-// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility
-// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility -x c++
+// RUN: %clang_cc1 %s -verify=stock,c -fsyntax-only
+// RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -x c++
+// RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -fms-compatibility -x c++
+// RUN: %clang_cc1 %s -verify=stock,c,gnu -fsyntax-only 
-Wgnu-flexible-array-union-member -Wgnu-empty-struct
+// RUN: %clang_cc1 %s -verify=stock,c,microsoft -fsyntax-only 
-fms-compatibility -Wmicrosoft
 
 // The test checks that an attempt to initialize union with flexible array
 // member with an initializer list doesn't crash clang.
 
 
-union { char x[]; } r = {0}; // c-error {{flexible array member 'x' in a union 
is not allowed}}
+union { char x[]; } r = {0}; /* gnu-warning {{flexible array member 'x' in a 
union is a GNU extension}}
+                                microsoft-warning {{flexible array member 'x' 
in a union is a Microsoft extension}}
+                              */
+struct _name1 {
+  int a;
+  union {
+    int b;
+    char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU 
extension}}
+                 microsoft-warning {{flexible array member 'x' in a union is a 
Microsoft extension}}
+               */
+  };
+} name1 = {
+  10,
+  42,        /* initializes "b" */
+};
 
-// expected-no-diagnostics
+struct _name1i {
+  int a;
+  union {
+    int b;
+    char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU 
extension}}
+                 microsoft-warning {{flexible array member 'x' in a union is a 
Microsoft extension}}
+               */
+  };
+} name1i = {
+  .a = 10,
+  .b = 42,
+};
+
+/* Initialization of flexible array in a union is never allowed. */
+struct _name2 {
+  int a;
+  union {
+    int b;
+    char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU 
extension}}
+                 microsoft-warning {{flexible array member 'x' in a union is a 
Microsoft extension}}
+                 stock-note {{initialized flexible array member 'x' is here}}
+               */
+  };
+} name2 = {
+  12,
+  13,
+  { 'c' },   /* stock-error {{initialization of flexible array member is not 
allowed}} */
----------------
kees wrote:

Yeah, I see what you mean. It looks like (when not using named initializers) a 
union initializer is applied to the first member. (i.e. when the type is 
anything other than a flexible array.) When it's a flex array, it processes it 
but only allows it to be zero initialized. Regardless, here's the results for 
unnamed initializers:

```
struct { int a; union { int b; short x; }; int c; int d; } h = {1, 2, {}, 3};
// @h = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, 
i32 3 }
struct { int a; union { int b; short x[0]; }; int c; int d; } h0 = {1, 2, {}, 
3};
// @h0 = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, 
i32 3 }
struct { int a; union { int b; short x[1]; }; int c; int d; } h1 = {1, 2, {}, 
3};
// @h1 = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, 
i32 3 }
struct { int a; union { int b; short x[]; }; int c; int d; } hf = {1, 2, {}, 3};
// @hf = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 3, 
i32 0 }
```

`hf` has clearly gone weird.

And here's what happens when using named initializers:

```
struct { int a; union { int b; short x; }; int c; int d; } hn = {.a = 1, .x = 
2, .c = 3};
// @hn = global { i32, { i16, [2 x i8] }, i32, i32 } { i32 1, { i16, [2 x i8] } 
{ i16 2, [2 x i8] undef }, i32 3, i32 0 }
struct { int a; union { int b; short x[0]; }; int c; int d; } hn0 = {.a = 1, .x 
= {2}, .c = 3};
// @hn0 = global { i32, { [0 x i16], [4 x i8] }, i32, i32 } { i32 1, { [0 x 
i16], [4 x i8] } { [0 x i16] zeroinitializer, [4 x i8] undef }, i32 3, i32 0 }
struct { int a; union { int b; short x[1]; }; int c; int d; } hn1 = {.a = 1, .x 
= {2}, .c = 3};
// @hn1 = global { i32, { [1 x i16], [2 x i8] }, i32, i32 } { i32 1, { [1 x 
i16], [2 x i8] } { [1 x i16] [i16 2], [2 x i8] undef }, i32 3, i32 0 }
```

The initialization of `x` in `hn0` just disappears, but it does generate the 
warning `excess elements in array initializer`, which I guess makes sense if 
it's not treating it as a fake flexible array?

Notably tttempting to initialize the flexible array by name will fail to build:
```
/srv/code/llvm-project/clang/test/CodeGen/flexible-array-init.c:48:82: error: 
initialization of flexible array member is not allowed                          
                                          
   48 | struct { int a; union { int b; short x[]; }; int c; int d; } hnf = {.a 
= 1, .x = {2}, .c = 3 };                                                        
                                          
      |                                                                         
         ^          
```

Named initializers appears to be working as intended. But it seems that unnamed 
initializer parsing isn't skipping a flex array like it would for other types?


https://github.com/llvm/llvm-project/pull/84428
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to