Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.bin / xlint / lint1 / init.c
1 /*      $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $     */
2
3 /*
4  * Copyright (c) 1994, 1995 Jochen Pohl
5  * All Rights Reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Jochen Pohl for
18  *      The NetBSD Project.
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.
21  *
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
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #ifndef lint
35 static char rcsid[] = "$NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $";
36 #endif
37
38 #include <stdlib.h>
39
40 #include "lint1.h"
41
42 /*
43  * initerr is set as soon as a fatal error occured in an initialisation.
44  * The effect is that the rest of the initialisation is ignored (parsed
45  * by yacc, expression trees built, but no initialisation takes place).
46  */
47 int     initerr;
48
49 /* Pointer to the symbol which is to be initialized. */
50 sym_t   *initsym;
51
52 /* Points to the top element of the initialisation stack. */
53 istk_t  *initstk;
54
55
56 static  void    popi2 __P((void));
57 static  void    popinit __P((int));
58 static  void    pushinit __P((void));
59 static  void    testinit __P((void));
60 static  void    nextinit __P((int));
61 static  int     strginit __P((tnode_t *));
62
63
64 /*
65  * Initialize the initialisation stack by putting an entry for the variable
66  * which is to be initialized on it.
67  */
68 void
69 prepinit()
70 {
71         istk_t  *istk;
72
73         if (initerr)
74                 return;
75
76         /* free memory used in last initialisation */
77         while ((istk = initstk) != NULL) {
78                 initstk = istk->i_nxt;
79                 free(istk);
80         }
81
82         /*
83          * If the type which is to be initialized is an incomplete type,
84          * it must be duplicated.
85          */
86         if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
87                 initsym->s_type = duptyp(initsym->s_type);
88
89         istk = initstk = xcalloc(1, sizeof (istk_t));
90         istk->i_subt = initsym->s_type;
91         istk->i_cnt = 1;
92
93 }
94
95 static void
96 popi2()
97 {
98         istk_t  *istk;
99         sym_t   *m;
100
101         initstk = (istk = initstk)->i_nxt;
102         if (initstk == NULL)
103                 lerror("popi2() 1");
104         free(istk);
105
106         istk = initstk;
107
108         istk->i_cnt--;
109         if (istk->i_cnt < 0)
110                 lerror("popi2() 3");
111
112         /*
113          * If the removed element was a structure member, we must go
114          * to the next structure member.
115          */
116         if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
117                 do {
118                         m = istk->i_mem = istk->i_mem->s_nxt;
119                         if (m == NULL)
120                                 lerror("popi2() 2");
121                 } while (m->s_field && m->s_name == unnamed);
122                 istk->i_subt = m->s_type;
123         }
124 }
125
126 static void
127 popinit(brace)
128         int     brace;
129 {
130         if (brace) {
131                 /*
132                  * Take all entries, including the first which requires
133                  * a closing brace, from the stack.
134                  */
135                 do {
136                         brace = initstk->i_brace;
137                         popi2();
138                 } while (!brace);
139         } else {
140                 /*
141                  * Take all entries which cannot be used for further
142                  * initializers from the stack, but do this only if
143                  * they do not require a closing brace.
144                  */
145                 while (!initstk->i_brace &&
146                        initstk->i_cnt == 0 && !initstk->i_nolimit) {
147                         popi2();
148                 }
149         }
150 }
151
152 static void
153 pushinit()
154 {
155         istk_t  *istk;
156         int     cnt;
157         sym_t   *m;
158
159         istk = initstk;
160
161         /* Extend an incomplete array type by one element */
162         if (istk->i_cnt == 0) {
163                 /*
164                  * Inside of other aggregate types must not be an incomplete
165                  * type.
166                  */
167                 if (istk->i_nxt->i_nxt != NULL)
168                         lerror("pushinit() 1");
169                 istk->i_cnt = 1;
170                 if (istk->i_type->t_tspec != ARRAY)
171                         lerror("pushinit() 2");
172                 istk->i_type->t_dim++;
173                 /* from now its an complete type */
174                 setcompl(istk->i_type, 0);
175         }
176
177         if (istk->i_cnt <= 0)
178                 lerror("pushinit() 3");
179         if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
180                 lerror("pushinit() 4");
181
182         initstk = xcalloc(1, sizeof (istk_t));
183         initstk->i_nxt = istk;
184         initstk->i_type = istk->i_subt;
185         if (initstk->i_type->t_tspec == FUNC)
186                 lerror("pushinit() 5");
187
188         istk = initstk;
189
190         switch (istk->i_type->t_tspec) {
191         case ARRAY:
192                 if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
193                         /* initialisation of an incomplete type */
194                         error(175);
195                         initerr = 1;
196                         return;
197                 }
198                 istk->i_subt = istk->i_type->t_subt;
199                 istk->i_nolimit = incompl(istk->i_type);
200                 istk->i_cnt = istk->i_type->t_dim;
201                 break;
202         case UNION:
203                 if (tflag)
204                         /* initialisation of union is illegal in trad. C */
205                         warning(238);
206                 /* FALLTHROUGH */
207         case STRUCT:
208                 if (incompl(istk->i_type)) {
209                         /* initialisation of an incomplete type */
210                         error(175);
211                         initerr = 1;
212                         return;
213                 }
214                 cnt = 0;
215                 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
216                         if (m->s_field && m->s_name == unnamed)
217                                 continue;
218                         if (++cnt == 1) {
219                                 istk->i_mem = m;
220                                 istk->i_subt = m->s_type;
221                         }
222                 }
223                 if (cnt == 0) {
224                         /* cannot init. struct/union with no named member */
225                         error(179);
226                         initerr = 1;
227                         return;
228                 }
229                 istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
230                 break;
231         default:
232                 istk->i_cnt = 1;
233                 break;
234         }
235 }
236
237 static void
238 testinit()
239 {
240         istk_t  *istk;
241
242         istk = initstk;
243
244         /*
245          * If a closing brace is expected we have at least one initializer
246          * too much.
247          */
248         if (istk->i_cnt == 0 && !istk->i_nolimit) {
249                 switch (istk->i_type->t_tspec) {
250                 case ARRAY:
251                         /* too many array initializers */
252                         error(173);
253                         break;
254                 case STRUCT:
255                 case UNION:
256                         /* too many struct/union initializers */
257                         error(172);
258                         break;
259                 default:
260                         /* too many initializers */
261                         error(174);
262                         break;
263                 }
264                 initerr = 1;
265         }
266 }
267
268 static void
269 nextinit(brace)
270         int     brace;
271 {
272         if (!brace) {
273                 if (initstk->i_type == NULL &&
274                     !issclt(initstk->i_subt->t_tspec)) {
275                         /* {}-enclosed initializer required */
276                         error(181);
277                 }
278                 /*
279                  * Make sure an entry with a scalar type is at the top
280                  * of the stack.
281                  */
282                 if (!initerr)
283                         testinit();
284                 while (!initerr && (initstk->i_type == NULL ||
285                                     !issclt(initstk->i_type->t_tspec))) {
286                         if (!initerr)
287                                 pushinit();
288                 }
289         } else {
290                 if (initstk->i_type != NULL &&
291                     issclt(initstk->i_type->t_tspec)) {
292                         /* invalid initializer */
293                         error(176);
294                         initerr = 1;
295                 }
296                 if (!initerr)
297                         testinit();
298                 if (!initerr)
299                         pushinit();
300                 if (!initerr)
301                         initstk->i_brace = 1;
302         }
303 }
304
305 void
306 initlbr()
307 {
308         if (initerr)
309                 return;
310
311         if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
312             initstk->i_nxt == NULL) {
313                 if (tflag && !issclt(initstk->i_subt->t_tspec))
314                         /* no automatic aggregate initialization in trad. C*/
315                         warning(188);
316         }
317
318         /*
319          * Remove all entries which cannot be used for further initializers
320          * and do not expect a closing brace.
321          */
322         popinit(0);
323
324         nextinit(1);
325 }
326
327 void
328 initrbr()
329 {
330         if (initerr)
331                 return;
332
333         popinit(1);
334 }
335
336 void
337 mkinit(tn)
338         tnode_t *tn;
339 {
340         ptrdiff_t offs;
341         sym_t   *sym;
342         tspec_t lt, rt;
343         tnode_t *ln;
344         struct  mbl *tmem;
345         scl_t   sc;
346
347         if (initerr || tn == NULL)
348                 goto end;
349
350         sc = initsym->s_scl;
351
352         /*
353          * Do not test for automatic aggregat initialisation. If the
354          * initalizer starts with a brace we have the warning already.
355          * If not, an error will be printed that the initializer must
356          * be enclosed by braces.
357          */
358
359         /*
360          * Local initialisation of non-array-types with only one expression
361          * without braces is done by ASSIGN
362          */
363         if ((sc == AUTO || sc == REG) &&
364             initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
365                 ln = getnnode(initsym, 0);
366                 ln->tn_type = tduptyp(ln->tn_type);
367                 ln->tn_type->t_const = 0;
368                 tn = build(ASSIGN, ln, tn);
369                 expr(tn, 0, 0);
370                 goto end;
371         }
372
373         /*
374          * Remove all entries which cannot be used for further initializers
375          * and do not require a closing brace.
376          */
377         popinit(0);
378
379         /* Initialisations by strings are done in strginit(). */
380         if (strginit(tn))
381                 goto end;
382
383         nextinit(0);
384         if (initerr || tn == NULL)
385                 goto end;
386
387         initstk->i_cnt--;
388
389         /* Create a temporary node for the left side. */
390         ln = tgetblk(sizeof (tnode_t));
391         ln->tn_op = NAME;
392         ln->tn_type = tduptyp(initstk->i_type);
393         ln->tn_type->t_const = 0;
394         ln->tn_lvalue = 1;
395         ln->tn_sym = initsym;           /* better than nothing */
396
397         tn = cconv(tn);
398
399         lt = ln->tn_type->t_tspec;
400         rt = tn->tn_type->t_tspec;
401
402         if (!issclt(lt))
403                 lerror("mkinit() 1");
404
405         if (!typeok(INIT, 0, ln, tn))
406                 goto end;
407
408         /*
409          * Store the tree memory. This is nessesary because otherwise
410          * expr() would free it.
411          */
412         tmem = tsave();
413         expr(tn, 1, 0);
414         trestor(tmem);
415         
416         if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
417                 /*
418                  * Bit-fields can be initialized in trad. C only by integer
419                  * constants.
420                  */
421                 if (tflag)
422                         /* bit-field initialisation is illegal in trad. C */
423                         warning(186);
424         }
425
426         if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
427                 tn = convert(INIT, 0, initstk->i_type, tn);
428
429         if (tn != NULL && tn->tn_op != CON) {
430                 sym = NULL;
431                 offs = 0;
432                 if (conaddr(tn, &sym, &offs) == -1) {
433                         if (sc == AUTO || sc == REG) {
434                                 /* non-constant initializer */
435                                 (void)gnuism(177);
436                         } else {
437                                 /* non-constant initializer */
438                                 error(177);
439                         }
440                 }
441         }
442
443  end:
444         tfreeblk();
445 }
446
447
448 static int
449 strginit(tn)
450         tnode_t *tn;
451 {
452         tspec_t t;
453         istk_t  *istk;
454         int     len;
455         strg_t  *strg;
456
457         if (tn->tn_op != STRING)
458                 return (0);
459
460         istk = initstk;
461         strg = tn->tn_strg;
462
463         /*
464          * Check if we have an array type which can be initialized by
465          * the string.
466          */
467         if (istk->i_subt->t_tspec == ARRAY) {
468                 t = istk->i_subt->t_subt->t_tspec;
469                 if (!((strg->st_tspec == CHAR &&
470                        (t == CHAR || t == UCHAR || t == SCHAR)) ||
471                       (strg->st_tspec == WCHAR && t == WCHAR))) {
472                         return (0);
473                 }
474                 /* Put the array at top of stack */
475                 pushinit();
476                 istk = initstk;
477         } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
478                 t = istk->i_type->t_subt->t_tspec;
479                 if (!((strg->st_tspec == CHAR &&
480                        (t == CHAR || t == UCHAR || t == SCHAR)) ||
481                       (strg->st_tspec == WCHAR && t == WCHAR))) {
482                         return (0);
483                 }
484                 /*
485                  * If the array is already partly initialized, we are
486                  * wrong here.
487                  */
488                 if (istk->i_cnt != istk->i_type->t_dim)
489                         return (0);
490         } else {
491                 return (0);
492         }
493
494         /* Get length without trailing NUL character. */
495         len = strg->st_len;
496
497         if (istk->i_nolimit) {
498                 istk->i_nolimit = 0;
499                 istk->i_type->t_dim = len + 1;
500                 /* from now complete type */
501                 setcompl(istk->i_type, 0);
502         } else {
503                 if (istk->i_type->t_dim < len) {
504                         /* non-null byte ignored in string initializer */
505                         warning(187);
506                 }
507         }
508
509         /* In every case the array is initialized completely. */
510         istk->i_cnt = 0;
511
512         return (1);
513 }