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