]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - usr.bin/xlint/lint1/init.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / usr.bin / xlint / lint1 / init.c
1 /*      $NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv 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 #include <sys/cdefs.h>
35 #if defined(__RCSID) && !defined(lint)
36 __RCSID("$NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv Exp $");
37 #endif
38 __FBSDID("$FreeBSD$");
39
40 #include <ctype.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include "lint1.h"
45
46 /*
47  * initerr is set as soon as a fatal error occurred in an initialisation.
48  * The effect is that the rest of the initialisation is ignored (parsed
49  * by yacc, expression trees built, but no initialisation takes place).
50  */
51 int     initerr;
52
53 /* Pointer to the symbol which is to be initialized. */
54 sym_t   *initsym;
55
56 /* Points to the top element of the initialisation stack. */
57 istk_t  *initstk;
58
59 typedef struct namlist {
60         const char *n_name;
61         struct namlist *n_prev;
62         struct namlist *n_next;
63 } namlist_t;
64
65 /* Points to a c9x named member; */
66 namlist_t       *namedmem = NULL;
67
68
69 static  void    popi2(void);
70 static  void    popinit(int);
71 static  void    pushinit(void);
72 static  void    testinit(void);
73 static  void    nextinit(int);
74 static  int     strginit(tnode_t *);
75 static  void    memberpop(void);
76
77 #ifndef DEBUG
78 #define DPRINTF(a)
79 #else
80 #define DPRINTF(a) printf a
81 #endif
82
83 void
84 memberpush(sb)
85         sbuf_t *sb;
86 {
87         namlist_t *nam = xcalloc(1, sizeof (namlist_t)); 
88         nam->n_name = sb->sb_name;
89         DPRINTF(("memberpush = %s\n", nam->n_name));
90         if (namedmem == NULL) {
91                 nam->n_prev = nam->n_next = nam;
92                 namedmem = nam;
93         } else {
94                 namedmem->n_prev->n_next = nam;
95                 nam->n_prev = namedmem->n_prev;
96                 nam->n_next = namedmem;
97                 namedmem->n_prev = nam;
98         }
99 #if 0
100         nam->n_next = namedmem;
101         namedmem = nam;
102 #endif
103 }
104
105 static void
106 memberpop()
107 {
108         DPRINTF(("memberpop = %s\n", namedmem->n_name));
109         if (namedmem->n_next == namedmem) {
110                 free(namedmem);
111                 namedmem = NULL;
112         } else {
113                 namlist_t *nam = namedmem;
114                 namedmem = namedmem->n_next;
115                 free(nam);
116         }
117 #if 0
118         namedmem = namedmem->n_next;
119         free(nam);
120 #endif
121 }
122
123
124 /*
125  * Initialize the initialisation stack by putting an entry for the variable
126  * which is to be initialized on it.
127  */
128 void
129 prepinit(void)
130 {
131         istk_t  *istk;
132
133         if (initerr)
134                 return;
135
136         /* free memory used in last initialisation */
137         while ((istk = initstk) != NULL) {
138                 initstk = istk->i_nxt;
139                 free(istk);
140         }
141
142         /*
143          * If the type which is to be initialized is an incomplete type,
144          * it must be duplicated.
145          */
146         if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
147                 initsym->s_type = duptyp(initsym->s_type);
148
149         istk = initstk = xcalloc(1, sizeof (istk_t));
150         istk->i_subt = initsym->s_type;
151         istk->i_cnt = 1;
152
153 }
154
155 static void
156 popi2(void)
157 {
158 #ifdef DEBUG
159         char    buf[64];
160 #endif
161         istk_t  *istk;
162         sym_t   *m;
163
164         initstk = (istk = initstk)->i_nxt;
165         if (initstk == NULL)
166                 LERROR("popi2()");
167         free(istk);
168
169         istk = initstk;
170
171         istk->i_cnt--;
172         if (istk->i_cnt < 0)
173                 LERROR("popi2()");
174
175         DPRINTF(("popi2(): %d %s\n", istk->i_cnt,
176             namedmem ? namedmem->n_name : "*null*"));
177         if (istk->i_cnt >= 0 && namedmem != NULL) {
178                 DPRINTF(("popi2(): %d %s %s\n", istk->i_cnt,
179                     tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
180                 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
181                         if (m->s_field && m->s_name == unnamed)
182                                 continue;
183                         if (strcmp(m->s_name, namedmem->n_name) == 0) {
184                                 istk->i_subt = m->s_type;
185                                 istk->i_cnt++;
186                                 memberpop();
187                                 return;
188                         }
189                 }
190                 error(101, namedmem->n_name);
191                 memberpop();
192                 istk->i_namedmem = 1;
193                 return;
194         }
195         /*
196          * If the removed element was a structure member, we must go
197          * to the next structure member.
198          */
199         if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT &&
200             !istk->i_namedmem) {
201                 do {
202                         m = istk->i_mem = istk->i_mem->s_nxt;
203                         if (m == NULL)
204                                 LERROR("popi2()");
205                 } while (m->s_field && m->s_name == unnamed);
206                 istk->i_subt = m->s_type;
207         }
208 }
209
210 static void
211 popinit(int brace)
212 {
213         DPRINTF(("popinit(%d)\n", brace));
214
215         if (brace) {
216                 /*
217                  * Take all entries, including the first which requires
218                  * a closing brace, from the stack.
219                  */
220                 do {
221                         brace = initstk->i_brace;
222                         popi2();
223                 } while (!brace);
224         } else {
225                 /*
226                  * Take all entries which cannot be used for further
227                  * initializers from the stack, but do this only if
228                  * they do not require a closing brace.
229                  */
230                 while (!initstk->i_brace &&
231                        initstk->i_cnt == 0 && !initstk->i_nolimit) {
232                         popi2();
233                 }
234         }
235 }
236
237 static void
238 pushinit(void)
239 {
240 #ifdef DEBUG
241         char    buf[64];
242 #endif
243         istk_t  *istk;
244         int     cnt;
245         sym_t   *m;
246
247         istk = initstk;
248
249         /* Extend an incomplete array type by one element */
250         if (istk->i_cnt == 0) {
251                 DPRINTF(("pushinit(extend) %s\n", tyname(buf, sizeof(buf),
252                     istk->i_type)));
253                 /*
254                  * Inside of other aggregate types must not be an incomplete
255                  * type.
256                  */
257                 if (istk->i_nxt->i_nxt != NULL)
258                         LERROR("pushinit()");
259                 istk->i_cnt = 1;
260                 if (istk->i_type->t_tspec != ARRAY)
261                         LERROR("pushinit()");
262                 istk->i_type->t_dim++;
263                 /* from now its a complete type */
264                 setcompl(istk->i_type, 0);
265         }
266
267         if (istk->i_cnt <= 0)
268                 LERROR("pushinit()");
269         if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
270                 LERROR("pushinit() 4");
271
272         initstk = xcalloc(1, sizeof (istk_t));
273         initstk->i_nxt = istk;
274         initstk->i_type = istk->i_subt;
275         if (initstk->i_type->t_tspec == FUNC)
276                 LERROR("pushinit()");
277
278 again:
279         istk = initstk;
280
281         DPRINTF(("pushinit(%s)\n", tyname(buf, sizeof(buf), istk->i_type)));
282         switch (istk->i_type->t_tspec) {
283         case ARRAY:
284                 if (namedmem) {
285                         DPRINTF(("pushinit ARRAY %s\n", namedmem->n_name));
286                         free(istk);
287                         initstk = initstk->i_nxt;
288                         goto again;
289                 }
290                 if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
291                         /* initialisation of an incomplete type */
292                         error(175);
293                         initerr = 1;
294                         return;
295                 }
296                 istk->i_subt = istk->i_type->t_subt;
297                 istk->i_nolimit = incompl(istk->i_type);
298                 istk->i_cnt = istk->i_type->t_dim;
299                 DPRINTF(("elements array %s[%d] %s\n",
300                     tyname(buf, sizeof(buf), istk->i_subt), istk->i_cnt,
301                     namedmem ? namedmem->n_name : "*none*"));
302                 break;
303         case UNION:
304                 if (tflag)
305                         /* initialisation of union is illegal in trad. C */
306                         warning(238);
307                 /* FALLTHROUGH */
308         case STRUCT:
309                 if (incompl(istk->i_type)) {
310                         /* initialisation of an incomplete type */
311                         error(175);
312                         initerr = 1;
313                         return;
314                 }
315                 cnt = 0;
316                 DPRINTF(("2. member lookup %s %s\n",
317                     tyname(buf, sizeof(buf), istk->i_type),
318                     namedmem ? namedmem->n_name : "*none*"));
319                 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
320                         if (m->s_field && m->s_name == unnamed)
321                                 continue;
322                         if (namedmem != NULL) {
323                                 DPRINTF(("pushinit():[member:%s, looking:%s]\n",
324                                     m->s_name, namedmem->n_name));
325                                 if (strcmp(m->s_name, namedmem->n_name) == 0) {
326                                         cnt++;
327                                         break;
328                                 } else
329                                         continue;
330                         }
331                         if (++cnt == 1) {
332                                 istk->i_mem = m;
333                                 istk->i_subt = m->s_type;
334                         }
335                 }
336                 if (namedmem != NULL) {
337                         istk->i_namedmem = 1;
338                         if (m == NULL) {
339                                 error(101, namedmem->n_name);
340                                 initerr = 1;
341                         } else {
342                                 istk->i_mem = m;
343                                 istk->i_subt = m->s_type;
344                         }
345                         memberpop();
346                         cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
347                 }
348                 if (cnt == 0) {
349                         /* cannot init. struct/union with no named member */
350                         error(179);
351                         initerr = 1;
352                         return;
353                 }
354                 istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
355                 break;
356         default:
357                 if (namedmem) {
358                         DPRINTF(("pushinit(): pop\n"));
359                         free(istk);
360                         initstk = initstk->i_nxt;
361                         goto again;
362                 }
363                 istk->i_cnt = 1;
364                 break;
365         }
366 }
367
368 static void
369 testinit(void)
370 {
371         istk_t  *istk;
372
373         istk = initstk;
374
375         /*
376          * If a closing brace is expected we have at least one initializer
377          * too much.
378          */
379         if (istk->i_cnt == 0 && !istk->i_nolimit && !istk->i_namedmem) {
380                 switch (istk->i_type->t_tspec) {
381                 case ARRAY:
382                         /* too many array initializers */
383                         error(173);
384                         break;
385                 case STRUCT:
386                 case UNION:
387                         /* too many struct/union initializers */
388                         error(172);
389                         break;
390                 default:
391                         /* too many initializers */
392                         error(174);
393                         break;
394                 }
395                 initerr = 1;
396         }
397 }
398
399 static void
400 nextinit(int brace)
401 {
402         char buf[64];
403
404         DPRINTF(("nextinit(%d)\n", brace));
405         if (!brace) {
406                 if (initstk->i_type == NULL &&
407                     !issclt(initstk->i_subt->t_tspec)) {
408                         /* {}-enclosed initializer required */
409                         error(181);
410                 }
411                 /*
412                  * Make sure an entry with a scalar type is at the top
413                  * of the stack.
414                  */
415                 if (!initerr)
416                         testinit();
417                 while (!initerr && (initstk->i_type == NULL ||
418                                     !issclt(initstk->i_type->t_tspec))) {
419                         if (!initerr)
420                                 pushinit();
421                 }
422         } else {
423                 if (initstk->i_type != NULL &&
424                     issclt(initstk->i_type->t_tspec)) {
425                         /* invalid initializer */
426                         error(176);
427                         initerr = 1;
428                 }
429                 if (!initerr)
430                         testinit();
431                 if (!initerr)
432                         pushinit();
433                 if (!initerr)
434                         initstk->i_brace = 1;
435         }
436 }
437
438 void
439 initlbr(void)
440 {
441
442         if (initerr)
443                 return;
444
445         if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
446             initstk->i_nxt == NULL) {
447                 if (tflag && !issclt(initstk->i_subt->t_tspec))
448                         /* no automatic aggregate initialization in trad. C*/
449                         warning(188);
450         }
451
452         /*
453          * Remove all entries which cannot be used for further initializers
454          * and do not expect a closing brace.
455          */
456         popinit(0);
457
458         nextinit(1);
459 }
460
461 void
462 initrbr(void)
463 {
464
465         if (initerr)
466                 return;
467
468         popinit(1);
469 }
470
471 void
472 mkinit(tnode_t *tn)
473 {
474         ptrdiff_t offs;
475         sym_t   *sym;
476         tspec_t lt, rt;
477         tnode_t *ln;
478         struct  mbl *tmem;
479         scl_t   sc;
480 #ifdef DEBUG
481         char    buf[64];
482 #endif
483
484         DPRINTF(("mkinit(%s)\n", tyname(buf, sizeof(buf), tn->tn_type)));
485         if (initerr || tn == NULL)
486                 goto end;
487
488         sc = initsym->s_scl;
489
490         /*
491          * Do not test for automatic aggregate initialisation. If the
492          * initializer starts with a brace we have the warning already.
493          * If not, an error will be printed that the initializer must
494          * be enclosed by braces.
495          */
496
497         /*
498          * Local initialisation of non-array-types with only one expression
499          * without braces is done by ASSIGN
500          */
501         if ((sc == AUTO || sc == REG) &&
502             initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
503                 ln = getnnode(initsym, 0);
504                 ln->tn_type = tduptyp(ln->tn_type);
505                 ln->tn_type->t_const = 0;
506                 tn = build(ASSIGN, ln, tn);
507                 expr(tn, 0, 0, 1);
508                 goto end;
509         }
510
511         /*
512          * Remove all entries which cannot be used for further initializers
513          * and do not require a closing brace.
514          */
515         popinit(0);
516
517         /* Initialisations by strings are done in strginit(). */
518         if (strginit(tn))
519                 goto end;
520
521         nextinit(0);
522         if (initerr || tn == NULL)
523                 goto end;
524
525         initstk->i_cnt--;
526         DPRINTF(("mkinit() cnt=%d tn=%p\n", initstk->i_cnt, tn));
527         /* Create a temporary node for the left side. */
528         ln = tgetblk(sizeof (tnode_t));
529         ln->tn_op = NAME;
530         ln->tn_type = tduptyp(initstk->i_type);
531         ln->tn_type->t_const = 0;
532         ln->tn_lvalue = 1;
533         ln->tn_sym = initsym;           /* better than nothing */
534
535         tn = cconv(tn);
536
537         lt = ln->tn_type->t_tspec;
538         rt = tn->tn_type->t_tspec;
539
540         if (!issclt(lt))
541                 LERROR("mkinit()");
542
543         if (!typeok(INIT, 0, ln, tn))
544                 goto end;
545
546         /*
547          * Store the tree memory. This is nessesary because otherwise
548          * expr() would free it.
549          */
550         tmem = tsave();
551         expr(tn, 1, 0, 1);
552         trestor(tmem);
553
554         if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
555                 /*
556                  * Bit-fields can be initialized in trad. C only by integer
557                  * constants.
558                  */
559                 if (tflag)
560                         /* bit-field initialisation is illegal in trad. C */
561                         warning(186);
562         }
563
564         if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
565                 tn = convert(INIT, 0, initstk->i_type, tn);
566
567         if (tn != NULL && tn->tn_op != CON) {
568                 sym = NULL;
569                 offs = 0;
570                 if (conaddr(tn, &sym, &offs) == -1) {
571                         if (sc == AUTO || sc == REG) {
572                                 /* non-constant initializer */
573                                 (void)gnuism(177);
574                         } else {
575                                 /* non-constant initializer */
576                                 error(177);
577                         }
578                 }
579         }
580
581  end:
582         /*
583          * We only free the block, if we are not a compound declaration
584          * We know that the only symbols that start with a digit are the
585          * ones we allocate with mktempsym() for compound declarations
586          */
587         if (!isdigit((unsigned char)initsym->s_name[0]))
588                 tfreeblk();
589 }
590
591
592 static int
593 strginit(tnode_t *tn)
594 {
595         tspec_t t;
596         istk_t  *istk;
597         int     len;
598         strg_t  *strg;
599
600         if (tn->tn_op != STRING)
601                 return (0);
602
603         istk = initstk;
604         strg = tn->tn_strg;
605
606         /*
607          * Check if we have an array type which can be initialized by
608          * the string.
609          */
610         if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
611                 t = istk->i_subt->t_subt->t_tspec;
612                 if (!((strg->st_tspec == CHAR &&
613                        (t == CHAR || t == UCHAR || t == SCHAR)) ||
614                       (strg->st_tspec == WCHAR && t == WCHAR))) {
615                         return (0);
616                 }
617                 /* Put the array at top of stack */
618                 pushinit();
619                 istk = initstk;
620         } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
621                 t = istk->i_type->t_subt->t_tspec;
622                 if (!((strg->st_tspec == CHAR &&
623                        (t == CHAR || t == UCHAR || t == SCHAR)) ||
624                       (strg->st_tspec == WCHAR && t == WCHAR))) {
625                         return (0);
626                 }
627                 /*
628                  * If the array is already partly initialized, we are
629                  * wrong here.
630                  */
631                 if (istk->i_cnt != istk->i_type->t_dim)
632                         return (0);
633         } else {
634                 return (0);
635         }
636
637         /* Get length without trailing NUL character. */
638         len = strg->st_len;
639
640         if (istk->i_nolimit) {
641                 istk->i_nolimit = 0;
642                 istk->i_type->t_dim = len + 1;
643                 /* from now complete type */
644                 setcompl(istk->i_type, 0);
645         } else {
646                 if (istk->i_type->t_dim < len) {
647                         /* non-null byte ignored in string initializer */
648                         warning(187);
649                 }
650         }
651
652         /* In every case the array is initialized completely. */
653         istk->i_cnt = 0;
654
655         return (1);
656 }