Fri Jan 1 19:28:51 2021 UTC ()
lint: document that C99-style initialization is necessarily buggy


(rillig)
diff -r1.53 -r1.54 src/usr.bin/xlint/lint1/init.c

cvs diff -r1.53 -r1.54 src/usr.bin/xlint/lint1/init.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/init.c 2021/01/01 19:15:58 1.53
+++ src/usr.bin/xlint/lint1/init.c 2021/01/01 19:28:51 1.54
@@ -1,699 +1,712 @@ @@ -1,699 +1,712 @@
1/* $NetBSD: init.c,v 1.53 2021/01/01 19:15:58 rillig Exp $ */ 1/* $NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: init.c,v 1.53 2021/01/01 19:15:58 rillig Exp $"); 40__RCSID("$NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $");
41#endif 41#endif
42 42
43#include <ctype.h> 43#include <ctype.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46 46
47#include "lint1.h" 47#include "lint1.h"
48 48
49 49
50/* 50/*
51 * Type of stack which is used for initialisation of aggregate types. 51 * Type of stack which is used for initialisation of aggregate types.
 52 *
 53 * XXX: Since C99, a stack is an inappropriate data structure for modelling
 54 * an initialization, since the designators don't have to be listed in a
 55 * particular order and can designate parts of sub-objects. The member names
 56 * of non-leaf structs may thus appear repeatedly, as demonstrated in
 57 * d_init_pop_member.c.
 58 *
 59 * XXX: During initialization, there may be members of the top-level struct
 60 * that are partially initialized. The simple i_remaining cannot model this
 61 * appropriately.
 62 *
 63 * See C99 6.7.8, which spans 6 pages full of tricky details and carefully
 64 * selected examples.
52 */ 65 */
53typedef struct istk { 66typedef struct istk {
54 type_t *i_type; /* type of initialisation */ 67 type_t *i_type; /* type of initialisation */
55 type_t *i_subt; /* type of next level */ 68 type_t *i_subt; /* type of next level */
56 u_int i_brace : 1; /* need } for pop */ 69 u_int i_brace : 1; /* need } for pop */
57 u_int i_nolimit : 1; /* incomplete array type */ 70 u_int i_nolimit : 1; /* incomplete array type */
58 u_int i_namedmem : 1; /* has c9x named members */ 71 u_int i_namedmem : 1; /* has c9x named members */
59 sym_t *i_mem; /* next structure member */ 72 sym_t *i_mem; /* next structure member */
60 int i_remaining; /* # of remaining elements */ 73 int i_remaining; /* # of remaining elements */
61 struct istk *i_next; /* previous level */ 74 struct istk *i_next; /* previous level */
62} istk_t; 75} istk_t;
63 76
64typedef struct namlist { 77typedef struct namlist {
65 const char *n_name; 78 const char *n_name;
66 struct namlist *n_prev; 79 struct namlist *n_prev;
67 struct namlist *n_next; 80 struct namlist *n_next;
68} namlist_t; 81} namlist_t;
69 82
70 83
71/* 84/*
72 * initerr is set as soon as a fatal error occurred in an initialisation. 85 * initerr is set as soon as a fatal error occurred in an initialisation.
73 * The effect is that the rest of the initialisation is ignored (parsed 86 * The effect is that the rest of the initialisation is ignored (parsed
74 * by yacc, expression trees built, but no initialisation takes place). 87 * by yacc, expression trees built, but no initialisation takes place).
75 */ 88 */
76int initerr; 89int initerr;
77 90
78/* Pointer to the symbol which is to be initialized. */ 91/* Pointer to the symbol which is to be initialized. */
79sym_t *initsym; 92sym_t *initsym;
80 93
81/* Points to the top element of the initialisation stack. */ 94/* Points to the top element of the initialisation stack. */
82istk_t *initstk; 95istk_t *initstk;
83 96
84/* Points to a c9x named member; */ 97/* Points to a c9x named member; */
85namlist_t *namedmem = NULL; 98namlist_t *namedmem = NULL;
86 99
87 100
88static int initstack_string(tnode_t *); 101static int initstack_string(tnode_t *);
89 102
90#ifndef DEBUG 103#ifndef DEBUG
91#define DPRINTF(a) 104#define DPRINTF(a)
92#else 105#else
93#define DPRINTF(a) printf a 106#define DPRINTF(a) printf a
94#endif 107#endif
95 108
96void 109void
97push_member(sbuf_t *sb) 110push_member(sbuf_t *sb)
98{ 111{
99 namlist_t *nam = xcalloc(1, sizeof (namlist_t)); 112 namlist_t *nam = xcalloc(1, sizeof (namlist_t));
100 nam->n_name = sb->sb_name; 113 nam->n_name = sb->sb_name;
101 DPRINTF(("%s: %s %p\n", __func__, nam->n_name, nam)); 114 DPRINTF(("%s: %s %p\n", __func__, nam->n_name, nam));
102 if (namedmem == NULL) { 115 if (namedmem == NULL) {
103 /* 116 /*
104 * XXX: Why is this a circular list? 117 * XXX: Why is this a circular list?
105 * XXX: Why is this a doubly-linked list? 118 * XXX: Why is this a doubly-linked list?
106 * A simple stack should suffice. 119 * A simple stack should suffice.
107 */ 120 */
108 nam->n_prev = nam->n_next = nam; 121 nam->n_prev = nam->n_next = nam;
109 namedmem = nam; 122 namedmem = nam;
110 } else { 123 } else {
111 namedmem->n_prev->n_next = nam; 124 namedmem->n_prev->n_next = nam;
112 nam->n_prev = namedmem->n_prev; 125 nam->n_prev = namedmem->n_prev;
113 nam->n_next = namedmem; 126 nam->n_next = namedmem;
114 namedmem->n_prev = nam; 127 namedmem->n_prev = nam;
115 } 128 }
116} 129}
117 130
118static void 131static void
119pop_member(void) 132pop_member(void)
120{ 133{
121 DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); 134 DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem));
122 if (namedmem->n_next == namedmem) { 135 if (namedmem->n_next == namedmem) {
123 free(namedmem); 136 free(namedmem);
124 namedmem = NULL; 137 namedmem = NULL;
125 } else { 138 } else {
126 namlist_t *nam = namedmem; 139 namlist_t *nam = namedmem;
127 namedmem = namedmem->n_next; 140 namedmem = namedmem->n_next;
128 nam->n_prev->n_next = nam->n_next; 141 nam->n_prev->n_next = nam->n_next;
129 nam->n_next->n_prev = nam->n_prev; 142 nam->n_next->n_prev = nam->n_prev;
130 free(nam); 143 free(nam);
131 } 144 }
132} 145}
133 146
134 147
135/* 148/*
136 * Initialize the initialisation stack by putting an entry for the variable 149 * Initialize the initialisation stack by putting an entry for the variable
137 * which is to be initialized on it. 150 * which is to be initialized on it.
138 */ 151 */
139void 152void
140initstack_init(void) 153initstack_init(void)
141{ 154{
142 istk_t *istk; 155 istk_t *istk;
143 156
144 if (initerr) 157 if (initerr)
145 return; 158 return;
146 159
147 /* free memory used in last initialisation */ 160 /* free memory used in last initialisation */
148 while ((istk = initstk) != NULL) { 161 while ((istk = initstk) != NULL) {
149 initstk = istk->i_next; 162 initstk = istk->i_next;
150 free(istk); 163 free(istk);
151 } 164 }
152 165
153 DPRINTF(("%s\n", __func__)); 166 DPRINTF(("%s\n", __func__));
154 167
155 /* 168 /*
156 * If the type which is to be initialized is an incomplete type, 169 * If the type which is to be initialized is an incomplete type,
157 * it must be duplicated. 170 * it must be duplicated.
158 */ 171 */
159 if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type)) 172 if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
160 initsym->s_type = duptyp(initsym->s_type); 173 initsym->s_type = duptyp(initsym->s_type);
161 174
162 istk = initstk = xcalloc(1, sizeof (istk_t)); 175 istk = initstk = xcalloc(1, sizeof (istk_t));
163 istk->i_subt = initsym->s_type; 176 istk->i_subt = initsym->s_type;
164 istk->i_remaining = 1; 177 istk->i_remaining = 1;
165} 178}
166 179
167static void 180static void
168initstack_pop_item(void) 181initstack_pop_item(void)
169{ 182{
170#ifdef DEBUG 183#ifdef DEBUG
171 char buf[64]; 184 char buf[64];
172#endif 185#endif
173 istk_t *istk; 186 istk_t *istk;
174 sym_t *m; 187 sym_t *m;
175 188
176 istk = initstk; 189 istk = initstk;
177 DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__, 190 DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__,
178 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), 191 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
179 istk->i_brace, istk->i_remaining, istk->i_namedmem)); 192 istk->i_brace, istk->i_remaining, istk->i_namedmem));
180 193
181 initstk = istk->i_next; 194 initstk = istk->i_next;
182 free(istk); 195 free(istk);
183 istk = initstk; 196 istk = initstk;
184 lint_assert(istk != NULL); 197 lint_assert(istk != NULL);
185 198
186 DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__, 199 DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__,
187 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), 200 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
188 istk->i_brace, istk->i_remaining, istk->i_namedmem)); 201 istk->i_brace, istk->i_remaining, istk->i_namedmem));
189 202
190 istk->i_remaining--; 203 istk->i_remaining--;
191 lint_assert(istk->i_remaining >= 0); 204 lint_assert(istk->i_remaining >= 0);
192 205
193 DPRINTF(("%s: top remaining=%d rhs.name=%s\n", __func__, 206 DPRINTF(("%s: top remaining=%d rhs.name=%s\n", __func__,
194 istk->i_remaining, namedmem ? namedmem->n_name : "*null*")); 207 istk->i_remaining, namedmem ? namedmem->n_name : "*null*"));
195 208
196 if (istk->i_remaining >= 0 && namedmem != NULL) { 209 if (istk->i_remaining >= 0 && namedmem != NULL) {
197 210
198 DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n", 211 DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n",
199 __func__, istk->i_remaining, 212 __func__, istk->i_remaining,
200 tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name)); 213 tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
201 214
202 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { 215 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
203 DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__, 216 DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__,
204 m->s_name, namedmem->n_name)); 217 m->s_name, namedmem->n_name));
205 if (m->s_bitfield && m->s_name == unnamed) 218 if (m->s_bitfield && m->s_name == unnamed)
206 continue; 219 continue;
207 if (strcmp(m->s_name, namedmem->n_name) == 0) { 220 if (strcmp(m->s_name, namedmem->n_name) == 0) {
208 istk->i_subt = m->s_type; 221 istk->i_subt = m->s_type;
209 istk->i_remaining++; 222 istk->i_remaining++;
210 pop_member(); 223 pop_member();
211 return; 224 return;
212 } 225 }
213 } 226 }
214 /* undefined struct/union member: %s */ 227 /* undefined struct/union member: %s */
215 error(101, namedmem->n_name); 228 error(101, namedmem->n_name);
216 DPRINTF(("%s: end rhs.name=%s\n", __func__, namedmem->n_name)); 229 DPRINTF(("%s: end rhs.name=%s\n", __func__, namedmem->n_name));
217 pop_member(); 230 pop_member();
218 istk->i_namedmem = 1; 231 istk->i_namedmem = 1;
219 return; 232 return;
220 } 233 }
221 /* 234 /*
222 * If the removed element was a structure member, we must go 235 * If the removed element was a structure member, we must go
223 * to the next structure member. 236 * to the next structure member.
224 */ 237 */
225 if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT && 238 if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT &&
226 !istk->i_namedmem) { 239 !istk->i_namedmem) {
227 do { 240 do {
228 m = istk->i_mem = istk->i_mem->s_next; 241 m = istk->i_mem = istk->i_mem->s_next;
229 lint_assert(m != NULL); 242 lint_assert(m != NULL);
230 DPRINTF(("%s: pop %s\n", __func__, m->s_name)); 243 DPRINTF(("%s: pop %s\n", __func__, m->s_name));
231 } while (m->s_bitfield && m->s_name == unnamed); 244 } while (m->s_bitfield && m->s_name == unnamed);
232 istk->i_subt = m->s_type; 245 istk->i_subt = m->s_type;
233 } 246 }
234} 247}
235 248
236/* 249/*
237 * Take all entries, including the first which requires a closing brace, 250 * Take all entries, including the first which requires a closing brace,
238 * from the stack. 251 * from the stack.
239 */ 252 */
240static void 253static void
241initstack_pop_brace(void) 254initstack_pop_brace(void)
242{ 255{
243 int brace; 256 int brace;
244 257
245 DPRINTF(("%s\n", __func__)); 258 DPRINTF(("%s\n", __func__));
246 do { 259 do {
247 brace = initstk->i_brace; 260 brace = initstk->i_brace;
248 DPRINTF(("%s: loop brace=%d\n", __func__, brace)); 261 DPRINTF(("%s: loop brace=%d\n", __func__, brace));
249 initstack_pop_item(); 262 initstack_pop_item();
250 } while (!brace); 263 } while (!brace);
251 DPRINTF(("%s: done\n", __func__)); 264 DPRINTF(("%s: done\n", __func__));
252} 265}
253 266
254/* 267/*
255 * Take all entries which cannot be used for further initializers from the 268 * Take all entries which cannot be used for further initializers from the
256 * stack, but do this only if they do not require a closing brace. 269 * stack, but do this only if they do not require a closing brace.
257 */ 270 */
258static void 271static void
259initstack_pop_nobrace(void) 272initstack_pop_nobrace(void)
260{ 273{
261 274
262 DPRINTF(("%s\n", __func__)); 275 DPRINTF(("%s\n", __func__));
263 while (!initstk->i_brace && initstk->i_remaining == 0 && 276 while (!initstk->i_brace && initstk->i_remaining == 0 &&
264 !initstk->i_nolimit) 277 !initstk->i_nolimit)
265 initstack_pop_item(); 278 initstack_pop_item();
266 DPRINTF(("%s: done\n", __func__)); 279 DPRINTF(("%s: done\n", __func__));
267} 280}
268 281
269static void 282static void
270initstack_push(void) 283initstack_push(void)
271{ 284{
272#ifdef DEBUG 285#ifdef DEBUG
273 char buf[64]; 286 char buf[64];
274#endif 287#endif
275 istk_t *istk, *inxt; 288 istk_t *istk, *inxt;
276 int cnt; 289 int cnt;
277 sym_t *m; 290 sym_t *m;
278 291
279 istk = initstk; 292 istk = initstk;
280 293
281 /* Extend an incomplete array type by one element */ 294 /* Extend an incomplete array type by one element */
282 if (istk->i_remaining == 0) { 295 if (istk->i_remaining == 0) {
283 DPRINTF(("%s(extend) %s\n", __func__, 296 DPRINTF(("%s(extend) %s\n", __func__,
284 tyname(buf, sizeof(buf), istk->i_type))); 297 tyname(buf, sizeof(buf), istk->i_type)));
285 /* 298 /*
286 * Inside of other aggregate types must not be an incomplete 299 * Inside of other aggregate types must not be an incomplete
287 * type. 300 * type.
288 */ 301 */
289 lint_assert(istk->i_next->i_next == NULL); 302 lint_assert(istk->i_next->i_next == NULL);
290 istk->i_remaining = 1; 303 istk->i_remaining = 1;
291 lint_assert(istk->i_type->t_tspec == ARRAY); 304 lint_assert(istk->i_type->t_tspec == ARRAY);
292 istk->i_type->t_dim++; 305 istk->i_type->t_dim++;
293 setcomplete(istk->i_type, 1); 306 setcomplete(istk->i_type, 1);
294 } 307 }
295 308
296 lint_assert(istk->i_remaining > 0); 309 lint_assert(istk->i_remaining > 0);
297 lint_assert(istk->i_type == NULL || 310 lint_assert(istk->i_type == NULL ||
298 !tspec_is_scalar(istk->i_type->t_tspec)); 311 !tspec_is_scalar(istk->i_type->t_tspec));
299 312
300 initstk = xcalloc(1, sizeof (istk_t)); 313 initstk = xcalloc(1, sizeof (istk_t));
301 initstk->i_next = istk; 314 initstk->i_next = istk;
302 initstk->i_type = istk->i_subt; 315 initstk->i_type = istk->i_subt;
303 lint_assert(initstk->i_type->t_tspec != FUNC); 316 lint_assert(initstk->i_type->t_tspec != FUNC);
304 317
305again: 318again:
306 istk = initstk; 319 istk = initstk;
307 320
308 DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type))); 321 DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type)));
309 switch (istk->i_type->t_tspec) { 322 switch (istk->i_type->t_tspec) {
310 case ARRAY: 323 case ARRAY:
311 if (namedmem) { 324 if (namedmem) {
312 DPRINTF(("%s: ARRAY %s brace=%d\n", __func__, 325 DPRINTF(("%s: ARRAY %s brace=%d\n", __func__,
313 namedmem->n_name, istk->i_brace)); 326 namedmem->n_name, istk->i_brace));
314 goto pop; 327 goto pop;
315 } else if (istk->i_next->i_namedmem) { 328 } else if (istk->i_next->i_namedmem) {
316 istk->i_brace = 1; 329 istk->i_brace = 1;
317 DPRINTF(("%s ARRAY brace=%d, namedmem=%d\n", __func__, 330 DPRINTF(("%s ARRAY brace=%d, namedmem=%d\n", __func__,
318 istk->i_brace, istk->i_next->i_namedmem)); 331 istk->i_brace, istk->i_next->i_namedmem));
319 } 332 }
320 333
321 if (incompl(istk->i_type) && istk->i_next->i_next != NULL) { 334 if (incompl(istk->i_type) && istk->i_next->i_next != NULL) {
322 /* initialisation of an incomplete type */ 335 /* initialisation of an incomplete type */
323 error(175); 336 error(175);
324 initerr = 1; 337 initerr = 1;
325 return; 338 return;
326 } 339 }
327 istk->i_subt = istk->i_type->t_subt; 340 istk->i_subt = istk->i_type->t_subt;
328 istk->i_nolimit = incompl(istk->i_type); 341 istk->i_nolimit = incompl(istk->i_type);
329 istk->i_remaining = istk->i_type->t_dim; 342 istk->i_remaining = istk->i_type->t_dim;
330 DPRINTF(("%s: elements array %s[%d] %s\n", __func__, 343 DPRINTF(("%s: elements array %s[%d] %s\n", __func__,
331 tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining, 344 tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining,
332 namedmem ? namedmem->n_name : "*none*")); 345 namedmem ? namedmem->n_name : "*none*"));
333 break; 346 break;
334 case UNION: 347 case UNION:
335 if (tflag) 348 if (tflag)
336 /* initialisation of union is illegal in trad. C */ 349 /* initialisation of union is illegal in trad. C */
337 warning(238); 350 warning(238);
338 /* FALLTHROUGH */ 351 /* FALLTHROUGH */
339 case STRUCT: 352 case STRUCT:
340 if (incompl(istk->i_type)) { 353 if (incompl(istk->i_type)) {
341 /* initialisation of an incomplete type */ 354 /* initialisation of an incomplete type */
342 error(175); 355 error(175);
343 initerr = 1; 356 initerr = 1;
344 return; 357 return;
345 } 358 }
346 cnt = 0; 359 cnt = 0;
347 DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__, 360 DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__,
348 tyname(buf, sizeof(buf), istk->i_type), 361 tyname(buf, sizeof(buf), istk->i_type),
349 namedmem ? namedmem->n_name : "*none*", istk->i_namedmem)); 362 namedmem ? namedmem->n_name : "*none*", istk->i_namedmem));
350 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { 363 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
351 if (m->s_bitfield && m->s_name == unnamed) 364 if (m->s_bitfield && m->s_name == unnamed)
352 continue; 365 continue;
353 if (namedmem != NULL) { 366 if (namedmem != NULL) {
354 DPRINTF(("%s: named lhs.member=%s, rhs.member=%s\n", 367 DPRINTF(("%s: named lhs.member=%s, rhs.member=%s\n",
355 __func__, m->s_name, namedmem->n_name)); 368 __func__, m->s_name, namedmem->n_name));
356 if (strcmp(m->s_name, namedmem->n_name) == 0) { 369 if (strcmp(m->s_name, namedmem->n_name) == 0) {
357 cnt++; 370 cnt++;
358 break; 371 break;
359 } else 372 } else
360 continue; 373 continue;
361 } 374 }
362 if (++cnt == 1) { 375 if (++cnt == 1) {
363 istk->i_mem = m; 376 istk->i_mem = m;
364 istk->i_subt = m->s_type; 377 istk->i_subt = m->s_type;
365 } 378 }
366 } 379 }
367 if (namedmem != NULL) { 380 if (namedmem != NULL) {
368 if (m == NULL) { 381 if (m == NULL) {
369 DPRINTF(("%s: pop struct\n", __func__)); 382 DPRINTF(("%s: pop struct\n", __func__));
370 goto pop; 383 goto pop;
371 } 384 }
372 istk->i_mem = m; 385 istk->i_mem = m;
373 istk->i_subt = m->s_type; 386 istk->i_subt = m->s_type;
374 istk->i_namedmem = 1; 387 istk->i_namedmem = 1;
375 DPRINTF(("%s: named name=%s\n", __func__, 388 DPRINTF(("%s: named name=%s\n", __func__,
376 namedmem->n_name)); 389 namedmem->n_name));
377 pop_member(); 390 pop_member();
378 cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1; 391 cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
379 } 392 }
380 istk->i_brace = 1; 393 istk->i_brace = 1;
381 DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__, 394 DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__,
382 tyname(buf, sizeof(buf), 395 tyname(buf, sizeof(buf),
383 istk->i_type ? istk->i_type : istk->i_subt), 396 istk->i_type ? istk->i_type : istk->i_subt),
384 istk->i_brace)); 397 istk->i_brace));
385 if (cnt == 0) { 398 if (cnt == 0) {
386 /* cannot init. struct/union with no named member */ 399 /* cannot init. struct/union with no named member */
387 error(179); 400 error(179);
388 initerr = 1; 401 initerr = 1;
389 return; 402 return;
390 } 403 }
391 istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1; 404 istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1;
392 break; 405 break;
393 default: 406 default:
394 if (namedmem) { 407 if (namedmem) {
395 DPRINTF(("%s: pop\n", __func__)); 408 DPRINTF(("%s: pop\n", __func__));
396 pop: 409 pop:
397 inxt = initstk->i_next; 410 inxt = initstk->i_next;
398 free(istk); 411 free(istk);
399 initstk = inxt; 412 initstk = inxt;
400 goto again; 413 goto again;
401 } 414 }
402 istk->i_remaining = 1; 415 istk->i_remaining = 1;
403 break; 416 break;
404 } 417 }
405} 418}
406 419
407static void 420static void
408initstack_check_too_many(void) 421initstack_check_too_many(void)
409{ 422{
410 istk_t *istk; 423 istk_t *istk;
411 424
412 istk = initstk; 425 istk = initstk;
413 426
414 /* 427 /*
415 * If a closing brace is expected we have at least one initializer 428 * If a closing brace is expected we have at least one initializer
416 * too much. 429 * too much.
417 */ 430 */
418 if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) { 431 if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) {
419 switch (istk->i_type->t_tspec) { 432 switch (istk->i_type->t_tspec) {
420 case ARRAY: 433 case ARRAY:
421 /* too many array initializers, expected %d */ 434 /* too many array initializers, expected %d */
422 error(173, istk->i_type->t_dim); 435 error(173, istk->i_type->t_dim);
423 break; 436 break;
424 case STRUCT: 437 case STRUCT:
425 case UNION: 438 case UNION:
426 /* too many struct/union initializers */ 439 /* too many struct/union initializers */
427 error(172); 440 error(172);
428 break; 441 break;
429 default: 442 default:
430 /* too many initializers */ 443 /* too many initializers */
431 error(174); 444 error(174);
432 break; 445 break;
433 } 446 }
434 initerr = 1; 447 initerr = 1;
435 } 448 }
436} 449}
437 450
438static void 451static void
439initstack_next_brace(void) 452initstack_next_brace(void)
440{ 453{
441 char buf[64]; 454 char buf[64];
442 455
443 DPRINTF(("%s\n", __func__)); 456 DPRINTF(("%s\n", __func__));
444 if (initstk->i_type != NULL && 457 if (initstk->i_type != NULL &&
445 tspec_is_scalar(initstk->i_type->t_tspec)) { 458 tspec_is_scalar(initstk->i_type->t_tspec)) {
446 /* invalid initializer type %s */ 459 /* invalid initializer type %s */
447 error(176, tyname(buf, sizeof(buf), initstk->i_type)); 460 error(176, tyname(buf, sizeof(buf), initstk->i_type));
448 initerr = 1; 461 initerr = 1;
449 } 462 }
450 if (!initerr) 463 if (!initerr)
451 initstack_check_too_many(); 464 initstack_check_too_many();
452 if (!initerr) 465 if (!initerr)
453 initstack_push(); 466 initstack_push();
454 if (!initerr) { 467 if (!initerr) {
455 initstk->i_brace = 1; 468 initstk->i_brace = 1;
456 DPRINTF(("%s: %p %s\n", __func__, 469 DPRINTF(("%s: %p %s\n", __func__,
457 namedmem, 470 namedmem,
458 tyname(buf, sizeof(buf), 471 tyname(buf, sizeof(buf),
459 initstk->i_type ? initstk->i_type : initstk->i_subt))); 472 initstk->i_type ? initstk->i_type : initstk->i_subt)));
460 } 473 }
461} 474}
462 475
463static void 476static void
464initstack_next_nobrace(void) 477initstack_next_nobrace(void)
465{ 478{
466 479
467 DPRINTF(("%s\n", __func__)); 480 DPRINTF(("%s\n", __func__));
468 if (initstk->i_type == NULL && 481 if (initstk->i_type == NULL &&
469 !tspec_is_scalar(initstk->i_subt->t_tspec)) { 482 !tspec_is_scalar(initstk->i_subt->t_tspec)) {
470 /* {}-enclosed initializer required */ 483 /* {}-enclosed initializer required */
471 error(181); 484 error(181);
472 } 485 }
473 486
474 /* Make sure an entry with a scalar type is at the top of the stack. */ 487 /* Make sure an entry with a scalar type is at the top of the stack. */
475 if (!initerr) 488 if (!initerr)
476 initstack_check_too_many(); 489 initstack_check_too_many();
477 while (!initerr) { 490 while (!initerr) {
478 if ((initstk->i_type != NULL && 491 if ((initstk->i_type != NULL &&
479 tspec_is_scalar(initstk->i_type->t_tspec))) 492 tspec_is_scalar(initstk->i_type->t_tspec)))
480 break; 493 break;
481 initstack_push(); 494 initstack_push();
482 } 495 }
483} 496}
484 497
485void 498void
486init_lbrace(void) 499init_lbrace(void)
487{ 500{
488 DPRINTF(("%s\n", __func__)); 501 DPRINTF(("%s\n", __func__));
489 502
490 if (initerr) 503 if (initerr)
491 return; 504 return;
492 505
493 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && 506 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
494 initstk->i_next == NULL) { 507 initstk->i_next == NULL) {
495 if (tflag && !tspec_is_scalar(initstk->i_subt->t_tspec)) 508 if (tflag && !tspec_is_scalar(initstk->i_subt->t_tspec))
496 /* no automatic aggregate initialization in trad. C */ 509 /* no automatic aggregate initialization in trad. C */
497 warning(188); 510 warning(188);
498 } 511 }
499 512
500 /* 513 /*
501 * Remove all entries which cannot be used for further initializers 514 * Remove all entries which cannot be used for further initializers
502 * and do not expect a closing brace. 515 * and do not expect a closing brace.
503 */ 516 */
504 initstack_pop_nobrace(); 517 initstack_pop_nobrace();
505 518
506 initstack_next_brace(); 519 initstack_next_brace();
507} 520}
508 521
509void 522void
510init_rbrace(void) 523init_rbrace(void)
511{ 524{
512 DPRINTF(("%s\n", __func__)); 525 DPRINTF(("%s\n", __func__));
513 526
514 if (initerr) 527 if (initerr)
515 return; 528 return;
516 529
517 initstack_pop_brace(); 530 initstack_pop_brace();
518} 531}
519 532
520void 533void
521mkinit(tnode_t *tn) 534mkinit(tnode_t *tn)
522{ 535{
523 ptrdiff_t offs; 536 ptrdiff_t offs;
524 sym_t *sym; 537 sym_t *sym;
525 tspec_t lt, rt; 538 tspec_t lt, rt;
526 tnode_t *ln; 539 tnode_t *ln;
527 struct mbl *tmem; 540 struct mbl *tmem;
528 scl_t sc; 541 scl_t sc;
529#ifdef DEBUG 542#ifdef DEBUG
530 char buf[64], sbuf[64]; 543 char buf[64], sbuf[64];
531#endif 544#endif
532 545
533 DPRINTF(("%s: type=%s, value=%s\n", __func__, 546 DPRINTF(("%s: type=%s, value=%s\n", __func__,
534 tyname(buf, sizeof(buf), tn->tn_type), 547 tyname(buf, sizeof(buf), tn->tn_type),
535 print_tnode(sbuf, sizeof(sbuf), tn))); 548 print_tnode(sbuf, sizeof(sbuf), tn)));
536 if (initerr || tn == NULL) 549 if (initerr || tn == NULL)
537 return; 550 return;
538 551
539 sc = initsym->s_scl; 552 sc = initsym->s_scl;
540 553
541 /* 554 /*
542 * Do not test for automatic aggregate initialisation. If the 555 * Do not test for automatic aggregate initialisation. If the
543 * initializer starts with a brace we have the warning already. 556 * initializer starts with a brace we have the warning already.
544 * If not, an error will be printed that the initializer must 557 * If not, an error will be printed that the initializer must
545 * be enclosed by braces. 558 * be enclosed by braces.
546 */ 559 */
547 560
548 /* 561 /*
549 * Local initialisation of non-array-types with only one expression 562 * Local initialisation of non-array-types with only one expression
550 * without braces is done by ASSIGN 563 * without braces is done by ASSIGN
551 */ 564 */
552 if ((sc == AUTO || sc == REG) && 565 if ((sc == AUTO || sc == REG) &&
553 initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) { 566 initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) {
554 ln = getnnode(initsym, 0); 567 ln = getnnode(initsym, 0);
555 ln->tn_type = tduptyp(ln->tn_type); 568 ln->tn_type = tduptyp(ln->tn_type);
556 ln->tn_type->t_const = 0; 569 ln->tn_type->t_const = 0;
557 tn = build(ASSIGN, ln, tn); 570 tn = build(ASSIGN, ln, tn);
558 expr(tn, 0, 0, 0); 571 expr(tn, 0, 0, 0);
559 return; 572 return;
560 } 573 }
561 574
562 /* 575 /*
563 * Remove all entries which cannot be used for further initializers 576 * Remove all entries which cannot be used for further initializers
564 * and do not require a closing brace. 577 * and do not require a closing brace.
565 */ 578 */
566 initstack_pop_nobrace(); 579 initstack_pop_nobrace();
567 580
568 /* Initialisations by strings are done in initstack_string(). */ 581 /* Initialisations by strings are done in initstack_string(). */
569 if (initstack_string(tn)) 582 if (initstack_string(tn))
570 return; 583 return;
571 584
572 initstack_next_nobrace(); 585 initstack_next_nobrace();
573 if (initerr || tn == NULL) 586 if (initerr || tn == NULL)
574 return; 587 return;
575 588
576 initstk->i_remaining--; 589 initstk->i_remaining--;
577 DPRINTF(("%s: remaining=%d tn=%p\n", __func__, 590 DPRINTF(("%s: remaining=%d tn=%p\n", __func__,
578 initstk->i_remaining, tn)); 591 initstk->i_remaining, tn));
579 /* Create a temporary node for the left side. */ 592 /* Create a temporary node for the left side. */
580 ln = tgetblk(sizeof (tnode_t)); 593 ln = tgetblk(sizeof (tnode_t));
581 ln->tn_op = NAME; 594 ln->tn_op = NAME;
582 ln->tn_type = tduptyp(initstk->i_type); 595 ln->tn_type = tduptyp(initstk->i_type);
583 ln->tn_type->t_const = 0; 596 ln->tn_type->t_const = 0;
584 ln->tn_lvalue = 1; 597 ln->tn_lvalue = 1;
585 ln->tn_sym = initsym; /* better than nothing */ 598 ln->tn_sym = initsym; /* better than nothing */
586 599
587 tn = cconv(tn); 600 tn = cconv(tn);
588 601
589 lt = ln->tn_type->t_tspec; 602 lt = ln->tn_type->t_tspec;
590 rt = tn->tn_type->t_tspec; 603 rt = tn->tn_type->t_tspec;
591 604
592 lint_assert(tspec_is_scalar(lt)); 605 lint_assert(tspec_is_scalar(lt));
593 606
594 if (!typeok(INIT, 0, ln, tn)) 607 if (!typeok(INIT, 0, ln, tn))
595 return; 608 return;
596 609
597 /* 610 /*
598 * Store the tree memory. This is necessary because otherwise 611 * Store the tree memory. This is necessary because otherwise
599 * expr() would free it. 612 * expr() would free it.
600 */ 613 */
601 tmem = tsave(); 614 tmem = tsave();
602 expr(tn, 1, 0, 1); 615 expr(tn, 1, 0, 1);
603 trestor(tmem); 616 trestor(tmem);
604 617
605 if (tspec_is_int(lt) && ln->tn_type->t_isfield && !tspec_is_int(rt)) { 618 if (tspec_is_int(lt) && ln->tn_type->t_isfield && !tspec_is_int(rt)) {
606 /* 619 /*
607 * Bit-fields can be initialized in trad. C only by integer 620 * Bit-fields can be initialized in trad. C only by integer
608 * constants. 621 * constants.
609 */ 622 */
610 if (tflag) 623 if (tflag)
611 /* bit-field initialisation is illegal in trad. C */ 624 /* bit-field initialisation is illegal in trad. C */
612 warning(186); 625 warning(186);
613 } 626 }
614 627
615 if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON)) 628 if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
616 tn = convert(INIT, 0, initstk->i_type, tn); 629 tn = convert(INIT, 0, initstk->i_type, tn);
617 630
618 if (tn != NULL && tn->tn_op != CON) { 631 if (tn != NULL && tn->tn_op != CON) {
619 sym = NULL; 632 sym = NULL;
620 offs = 0; 633 offs = 0;
621 if (conaddr(tn, &sym, &offs) == -1) { 634 if (conaddr(tn, &sym, &offs) == -1) {
622 if (sc == AUTO || sc == REG) { 635 if (sc == AUTO || sc == REG) {
623 /* non-constant initializer */ 636 /* non-constant initializer */
624 (void)c99ism(177); 637 (void)c99ism(177);
625 } else { 638 } else {
626 /* non-constant initializer */ 639 /* non-constant initializer */
627 error(177); 640 error(177);
628 } 641 }
629 } 642 }
630 } 643 }
631} 644}
632 645
633 646
634static int 647static int
635initstack_string(tnode_t *tn) 648initstack_string(tnode_t *tn)
636{ 649{
637 tspec_t t; 650 tspec_t t;
638 istk_t *istk; 651 istk_t *istk;
639 int len; 652 int len;
640 strg_t *strg; 653 strg_t *strg;
641 654
642 if (tn->tn_op != STRING) 655 if (tn->tn_op != STRING)
643 return 0; 656 return 0;
644 657
645 istk = initstk; 658 istk = initstk;
646 strg = tn->tn_string; 659 strg = tn->tn_string;
647 660
648 /* 661 /*
649 * Check if we have an array type which can be initialized by 662 * Check if we have an array type which can be initialized by
650 * the string. 663 * the string.
651 */ 664 */
652 if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) { 665 if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
653 DPRINTF(("%s: subt array\n", __func__)); 666 DPRINTF(("%s: subt array\n", __func__));
654 t = istk->i_subt->t_subt->t_tspec; 667 t = istk->i_subt->t_subt->t_tspec;
655 if (!((strg->st_tspec == CHAR && 668 if (!((strg->st_tspec == CHAR &&
656 (t == CHAR || t == UCHAR || t == SCHAR)) || 669 (t == CHAR || t == UCHAR || t == SCHAR)) ||
657 (strg->st_tspec == WCHAR && t == WCHAR))) { 670 (strg->st_tspec == WCHAR && t == WCHAR))) {
658 return 0; 671 return 0;
659 } 672 }
660 /* Put the array at top of stack */ 673 /* Put the array at top of stack */
661 initstack_push(); 674 initstack_push();
662 istk = initstk; 675 istk = initstk;
663 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) { 676 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
664 DPRINTF(("%s: type array\n", __func__)); 677 DPRINTF(("%s: type array\n", __func__));
665 t = istk->i_type->t_subt->t_tspec; 678 t = istk->i_type->t_subt->t_tspec;
666 if (!((strg->st_tspec == CHAR && 679 if (!((strg->st_tspec == CHAR &&
667 (t == CHAR || t == UCHAR || t == SCHAR)) || 680 (t == CHAR || t == UCHAR || t == SCHAR)) ||
668 (strg->st_tspec == WCHAR && t == WCHAR))) { 681 (strg->st_tspec == WCHAR && t == WCHAR))) {
669 return 0; 682 return 0;
670 } 683 }
671 /* 684 /*
672 * If the array is already partly initialized, we are 685 * If the array is already partly initialized, we are
673 * wrong here. 686 * wrong here.
674 */ 687 */
675 if (istk->i_remaining != istk->i_type->t_dim) 688 if (istk->i_remaining != istk->i_type->t_dim)
676 return 0; 689 return 0;
677 } else { 690 } else {
678 return 0; 691 return 0;
679 } 692 }
680 693
681 /* Get length without trailing NUL character. */ 694 /* Get length without trailing NUL character. */
682 len = strg->st_len; 695 len = strg->st_len;
683 696
684 if (istk->i_nolimit) { 697 if (istk->i_nolimit) {
685 istk->i_nolimit = 0; 698 istk->i_nolimit = 0;
686 istk->i_type->t_dim = len + 1; 699 istk->i_type->t_dim = len + 1;
687 setcomplete(istk->i_type, 1); 700 setcomplete(istk->i_type, 1);
688 } else { 701 } else {
689 if (istk->i_type->t_dim < len) { 702 if (istk->i_type->t_dim < len) {
690 /* non-null byte ignored in string initializer */ 703 /* non-null byte ignored in string initializer */
691 warning(187); 704 warning(187);
692 } 705 }
693 } 706 }
694 707
695 /* In every case the array is initialized completely. */ 708 /* In every case the array is initialized completely. */
696 istk->i_remaining = 0; 709 istk->i_remaining = 0;
697 710
698 return 1; 711 return 1;
699} 712}