aboutsummaryrefslogtreecommitdiff
path: root/clang/test/Sema/flexible-array-in-union.c
blob: dd5e8069665feabe88c56db27b6747d35fd6d4c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// 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}; /* 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" */
};

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}}
               */
  };
} name2 = {
  12,
  13,
  { 'c' },   /* c-warning {{excess elements in struct initializer}}
                cpp-error {{excess elements in struct initializer}}
              */
};

/* Initialization of flexible array in a union is never allowed. */
struct _name2i {
  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}}
               */
  };
} name2i = {
  .a = 12,
  .b = 13,      /* stock-note {{previous initialization is here}} */
  .x = { 'c' }, /* stock-error {{initialization of flexible array member is not allowed}}
                   c-warning {{initializer overrides prior initialization of this subobject}}
                   cpp-error {{initializer partially overrides prior initialization of this subobject}}
                 */
};

/* Flexible array initialization always allowed when not in a union,
   and when struct has another member.
 */
struct _okay {
  int a;
  char x[];
} okay = {
  22,
  { 'x', 'y', 'z' },
};

struct _okayi {
  int a;
  char x[];
} okayi = {
  .a = 22,
  .x = { 'x', 'y', 'z' },
};

struct _okay0 {
  int a;
  char x[];
} okay0 = { };

struct _flex_extension {
  char x[]; /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}}
               microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}}
             */
} flex_extension = {
  { 'x', 'y', 'z' },
};

struct _flex_extensioni {
  char x[]; /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}}
               microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}}
             */
} flex_extensioni = {
  .x = { 'x', 'y', 'z' },
};

struct already_hidden {
  int a;
  union {
    int b;
    struct {
      struct { } __empty;  // gnu-warning {{empty struct is a GNU extension}}
      char x[];
    };
  };
};

struct still_zero_sized {
  struct { } __unused;  // gnu-warning {{empty struct is a GNU extension}}
  int x[];
};

struct warn1 {
  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}}
               */
  };
};

struct warn2 {
  int x[];  /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}}
               microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}}
             */
};

union warn3 {
  short 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}}
               */
};

struct quiet1 {
  int a;
  short x[];
};

struct _not_at_end {
  union { short x[]; }; /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}}
                           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}}
                         */
  int y;
} not_at_end = {{}, 3};

struct _not_at_end_s {
  struct { int a; short x[]; }; /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}} */
  int y;
} not_at_end_s = {{}, 3};

struct {
  int a;
  union {      /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}} */
    short x[]; /* stock-note {{initialized flexible array member 'x' is here}}
                  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}}
                */
    int b;
  };
  int c;
  int d;
} i_f = { 4,
         {5},  /* stock-error {{initialization of flexible array member is not allowed}} */
         {},
          6};

// expected-no-diagnostics