init.c revision 1.74 1 /* $NetBSD: init.c,v 1.74 2021/02/20 19:10:38 rillig 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 #if HAVE_NBTOOL_CONFIG_H
35 #include "nbtool_config.h"
36 #endif
37
38 #include <sys/cdefs.h>
39 #if defined(__RCSID) && !defined(lint)
40 __RCSID("$NetBSD: init.c,v 1.74 2021/02/20 19:10:38 rillig Exp $");
41 #endif
42
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "lint1.h"
47
48
49 /*
50 * Type of stack which is used for initialisation of aggregate types.
51 *
52 * XXX: Since C99, a stack is an inappropriate data structure for modelling
53 * an initialization, since the designators don't have to be listed in a
54 * particular order and can designate parts of sub-objects. The member names
55 * of non-leaf structs may thus appear repeatedly, as demonstrated in
56 * d_init_pop_member.c.
57 *
58 * XXX: During initialization, there may be members of the top-level struct
59 * that are partially initialized. The simple i_remaining cannot model this
60 * appropriately.
61 *
62 * See C99 6.7.8, which spans 6 pages full of tricky details and carefully
63 * selected examples.
64 */
65 typedef struct istk {
66 type_t *i_type; /* type of initialisation */
67 type_t *i_subt; /* type of next level */
68 bool i_brace : 1; /* need } for pop */
69 bool i_nolimit : 1; /* incomplete array type */
70 bool i_namedmem : 1; /* has c9x named members */
71 sym_t *i_mem; /* next structure member */
72 int i_remaining; /* # of remaining elements */
73 struct istk *i_next; /* previous level */
74 } istk_t;
75
76 /*
77 * The names for a nested C99 initialization designator, in a circular list.
78 *
79 * Example:
80 * struct stat st = {
81 * .st_size = 123,
82 * .st_mtim.tv_sec = 45,
83 * .st_mtim.tv_nsec
84 * };
85 *
86 * During initialization, this list first contains ["st_size"], then
87 * ["st_mtim", "tv_sec"], then ["st_mtim", "tv_nsec"].
88 */
89 typedef struct namlist {
90 const char *n_name;
91 struct namlist *n_prev;
92 struct namlist *n_next;
93 } namlist_t;
94
95
96 /*
97 * initerr is set as soon as a fatal error occurred in an initialisation.
98 * The effect is that the rest of the initialisation is ignored (parsed
99 * by yacc, expression trees built, but no initialisation takes place).
100 */
101 bool initerr;
102
103 /* Pointer to the symbol which is to be initialized. */
104 sym_t *initsym;
105
106 /* Points to the top element of the initialisation stack. */
107 istk_t *initstk;
108
109 /* Points to a c9x named member; */
110 namlist_t *namedmem = NULL;
111
112
113 static bool initstack_string(tnode_t *);
114
115 #ifndef DEBUG
116 #define debug_printf(fmt, ...) (void)0
117 #define debug_indent() (void)0
118 #define debug_enter(a) (void)0
119 #define debug_step(fmt, ...) (void)0
120 #define debug_leave(a) (void)0
121 #else
122 static int debug_ind = 0;
123
124 static void __printflike(1, 2)
125 debug_printf(const char *fmt, ...)
126 {
127 va_list va;
128
129 va_start(va, fmt);
130 vfprintf(stdout, fmt, va);
131 va_end(va);
132 }
133
134 static void
135 debug_indent(void)
136 {
137 debug_printf("%*s", 2 * debug_ind, "");
138 }
139
140 static void
141 debug_enter(const char *func)
142 {
143 printf("%*s+ %s\n", 2 * debug_ind++, "", func);
144 }
145
146 static void __printflike(1, 2)
147 debug_step(const char *fmt, ...)
148 {
149 va_list va;
150
151 printf("%*s", 2 * debug_ind, "");
152 va_start(va, fmt);
153 vfprintf(stdout, fmt, va);
154 va_end(va);
155 printf("\n");
156 }
157
158 static void
159 debug_leave(const char *func)
160 {
161 printf("%*s- %s\n", 2 * --debug_ind, "", func);
162 }
163
164 #define debug_enter() debug_enter(__func__)
165 #define debug_leave() debug_leave(__func__)
166
167 #endif
168
169 void
170 push_member(sbuf_t *sb)
171 {
172 namlist_t *nam = xcalloc(1, sizeof (namlist_t));
173 nam->n_name = sb->sb_name;
174
175 debug_step("%s: '%s' %p", __func__, nam->n_name, nam);
176
177 if (namedmem == NULL) {
178 /*
179 * XXX: Why is this a circular list?
180 * XXX: Why is this a doubly-linked list?
181 * A simple stack should suffice.
182 */
183 nam->n_prev = nam->n_next = nam;
184 namedmem = nam;
185 } else {
186 namedmem->n_prev->n_next = nam;
187 nam->n_prev = namedmem->n_prev;
188 nam->n_next = namedmem;
189 namedmem->n_prev = nam;
190 }
191 }
192
193 static void
194 pop_member(void)
195 {
196 debug_step("%s: %s %p", __func__, namedmem->n_name, namedmem);
197 if (namedmem->n_next == namedmem) {
198 free(namedmem);
199 namedmem = NULL;
200 } else {
201 namlist_t *nam = namedmem;
202 namedmem = namedmem->n_next;
203 nam->n_prev->n_next = nam->n_next;
204 nam->n_next->n_prev = nam->n_prev;
205 free(nam);
206 }
207 }
208
209 #ifdef DEBUG
210 static void
211 debug_named_member(void)
212 {
213 namlist_t *name;
214
215 if (namedmem == NULL)
216 return;
217 name = namedmem;
218 debug_indent();
219 debug_printf("named member:");
220 do {
221 debug_printf(" %s", name->n_name);
222 name = name->n_next;
223 } while (name != namedmem);
224 debug_printf("\n");
225 }
226 #else
227 #define debug_named_member() (void)0
228 #endif
229
230 #ifdef DEBUG
231 static const char *
232 noyes(bool cond)
233 {
234 return cond ? "yes" : "no";
235 }
236
237 static void
238 debug_initstack(void)
239 {
240 if (initstk == NULL) {
241 debug_step("initstk is empty");
242 return;
243 }
244
245 size_t i = 0;
246 for (const istk_t *elem = initstk; elem != NULL; elem = elem->i_next) {
247 debug_step("initstk[%zu]:", i);
248 debug_step(" i_type = %s", type_name(elem->i_type));
249 debug_step(" i_subt = %s", type_name(elem->i_subt));
250 debug_step(" i_brace = %s", noyes(elem->i_brace));
251 debug_step(" i_nolimit = %s", noyes(elem->i_nolimit));
252 debug_step(" i_namedmem = %s", noyes(elem->i_namedmem));
253 debug_step(" i_mem = %s",
254 elem->i_mem != NULL ? elem->i_mem->s_name : "(null)");
255 debug_step(" i_remaining = %d", elem->i_remaining);
256 i++;
257 }
258 }
259 #else
260 #define debug_initstack() (void)0
261 #endif
262
263 /*
264 * Initialize the initialisation stack by putting an entry for the variable
265 * which is to be initialized on it.
266 */
267 void
268 initstack_init(void)
269 {
270 istk_t *istk;
271
272 if (initerr)
273 return;
274
275 /* free memory used in last initialisation */
276 while ((istk = initstk) != NULL) {
277 initstk = istk->i_next;
278 free(istk);
279 }
280
281 debug_enter();
282
283 /*
284 * If the type which is to be initialized is an incomplete type,
285 * it must be duplicated.
286 */
287 if (initsym->s_type->t_tspec == ARRAY && is_incomplete(initsym->s_type))
288 initsym->s_type = duptyp(initsym->s_type);
289
290 istk = initstk = xcalloc(1, sizeof (istk_t));
291 istk->i_subt = initsym->s_type;
292 istk->i_remaining = 1;
293
294 debug_initstack();
295 debug_leave();
296 }
297
298 static void
299 initstack_pop_item(void)
300 {
301 istk_t *istk;
302 sym_t *m;
303
304 debug_enter();
305
306 istk = initstk;
307 debug_step("pop type=%s, brace=%d remaining=%d named=%d",
308 type_name(istk->i_type != NULL ? istk->i_type : istk->i_subt),
309 istk->i_brace, istk->i_remaining, istk->i_namedmem);
310
311 initstk = istk->i_next;
312 free(istk);
313 istk = initstk;
314 lint_assert(istk != NULL);
315
316 debug_step("top type=%s, brace=%d remaining=%d named=%d",
317 type_name(istk->i_type != NULL ? istk->i_type : istk->i_subt),
318 istk->i_brace, istk->i_remaining, istk->i_namedmem);
319
320 istk->i_remaining--;
321 lint_assert(istk->i_remaining >= 0);
322
323 debug_step("top remaining=%d rhs.name=%s",
324 istk->i_remaining, namedmem != NULL ? namedmem->n_name : "*null*");
325
326 if (istk->i_remaining >= 0 && namedmem != NULL) {
327
328 debug_step("named remaining=%d type=%s, rhs.name=%s",
329 istk->i_remaining, type_name(istk->i_type),
330 namedmem->n_name);
331
332 for (m = istk->i_type->t_str->sou_first_member;
333 m != NULL; m = m->s_next) {
334 debug_step("pop lhs.name=%s rhs.name=%s",
335 m->s_name, namedmem->n_name);
336 if (m->s_bitfield && m->s_name == unnamed)
337 continue;
338 if (strcmp(m->s_name, namedmem->n_name) == 0) {
339 istk->i_subt = m->s_type;
340 istk->i_remaining++;
341 pop_member();
342 debug_initstack();
343 debug_leave();
344 return;
345 }
346 }
347 /* undefined struct/union member: %s */
348 error(101, namedmem->n_name);
349 debug_step("end rhs.name=%s", namedmem->n_name);
350 pop_member();
351 istk->i_namedmem = true;
352 debug_initstack();
353 debug_leave();
354 return;
355 }
356 /*
357 * If the removed element was a structure member, we must go
358 * to the next structure member.
359 */
360 if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT &&
361 !istk->i_namedmem) {
362 do {
363 m = istk->i_mem = istk->i_mem->s_next;
364 lint_assert(m != NULL);
365 debug_step("pop %s", m->s_name);
366 } while (m->s_bitfield && m->s_name == unnamed);
367 istk->i_subt = m->s_type;
368 }
369 debug_initstack();
370 debug_leave();
371 }
372
373 /*
374 * Take all entries, including the first which requires a closing brace,
375 * from the stack.
376 */
377 static void
378 initstack_pop_brace(void)
379 {
380 bool brace;
381
382 debug_enter();
383 debug_initstack();
384 do {
385 brace = initstk->i_brace;
386 debug_step("loop brace=%d", brace);
387 initstack_pop_item();
388 } while (!brace);
389 debug_initstack();
390 debug_leave();
391 }
392
393 /*
394 * Take all entries which cannot be used for further initializers from the
395 * stack, but do this only if they do not require a closing brace.
396 */
397 static void
398 initstack_pop_nobrace(void)
399 {
400
401 debug_enter();
402 debug_initstack();
403 while (!initstk->i_brace && initstk->i_remaining == 0 &&
404 !initstk->i_nolimit)
405 initstack_pop_item();
406 debug_initstack();
407 debug_leave();
408 }
409
410 static void
411 initstack_push(void)
412 {
413 istk_t *istk, *inxt;
414 int cnt;
415 sym_t *m;
416
417 debug_enter();
418 debug_initstack();
419
420 istk = initstk;
421
422 /* Extend an incomplete array type by one element */
423 if (istk->i_remaining == 0) {
424 debug_step("(extend) %s", type_name(istk->i_type));
425 /*
426 * Inside of other aggregate types must not be an incomplete
427 * type.
428 */
429 lint_assert(istk->i_next->i_next == NULL);
430 istk->i_remaining = 1;
431 lint_assert(istk->i_type->t_tspec == ARRAY);
432 istk->i_type->t_dim++;
433 setcomplete(istk->i_type, true);
434 }
435
436 lint_assert(istk->i_remaining > 0);
437 lint_assert(istk->i_type == NULL || !is_scalar(istk->i_type->t_tspec));
438
439 initstk = xcalloc(1, sizeof (istk_t));
440 initstk->i_next = istk;
441 initstk->i_type = istk->i_subt;
442 lint_assert(initstk->i_type->t_tspec != FUNC);
443
444 again:
445 istk = initstk;
446
447 debug_step("typename %s", type_name(istk->i_type));
448 switch (istk->i_type->t_tspec) {
449 case ARRAY:
450 if (namedmem != NULL) {
451 debug_step("ARRAY %s brace=%d",
452 namedmem->n_name, istk->i_brace);
453 goto pop;
454 } else if (istk->i_next->i_namedmem) {
455 istk->i_brace = true;
456 debug_step("ARRAY brace=%d, namedmem=%d",
457 istk->i_brace, istk->i_next->i_namedmem);
458 }
459
460 if (is_incomplete(istk->i_type) &&
461 istk->i_next->i_next != NULL) {
462 /* initialisation of an incomplete type */
463 error(175);
464 initerr = true;
465 debug_initstack();
466 debug_leave();
467 return;
468 }
469 istk->i_subt = istk->i_type->t_subt;
470 istk->i_nolimit = is_incomplete(istk->i_type);
471 istk->i_remaining = istk->i_type->t_dim;
472 debug_step("elements array %s[%d] %s",
473 type_name(istk->i_subt), istk->i_remaining,
474 namedmem != NULL ? namedmem->n_name : "*none*");
475 break;
476 case UNION:
477 if (tflag)
478 /* initialisation of union is illegal in trad. C */
479 warning(238);
480 /* FALLTHROUGH */
481 case STRUCT:
482 if (is_incomplete(istk->i_type)) {
483 /* initialisation of an incomplete type */
484 error(175);
485 initerr = true;
486 debug_initstack();
487 debug_leave();
488 return;
489 }
490 cnt = 0;
491 debug_step("lookup type=%s, name=%s named=%d",
492 type_name(istk->i_type),
493 namedmem != NULL ? namedmem->n_name : "*none*",
494 istk->i_namedmem);
495 for (m = istk->i_type->t_str->sou_first_member;
496 m != NULL; m = m->s_next) {
497 if (m->s_bitfield && m->s_name == unnamed)
498 continue;
499 if (namedmem != NULL) {
500 debug_step("named lhs.member=%s, rhs.member=%s",
501 m->s_name, namedmem->n_name);
502 if (strcmp(m->s_name, namedmem->n_name) == 0) {
503 cnt++;
504 break;
505 } else
506 continue;
507 }
508 if (++cnt == 1) {
509 istk->i_mem = m;
510 istk->i_subt = m->s_type;
511 }
512 }
513 if (namedmem != NULL) {
514 if (m == NULL) {
515 debug_step("pop struct");
516 goto pop;
517 }
518 istk->i_mem = m;
519 istk->i_subt = m->s_type;
520 istk->i_namedmem = true;
521 debug_step("named name=%s", namedmem->n_name);
522 pop_member();
523 cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
524 }
525 istk->i_brace = true;
526 debug_step("unnamed type=%s, brace=%d",
527 type_name(
528 istk->i_type != NULL ? istk->i_type : istk->i_subt),
529 istk->i_brace);
530 if (cnt == 0) {
531 /* cannot init. struct/union with no named member */
532 error(179);
533 initerr = true;
534 debug_initstack();
535 debug_leave();
536 return;
537 }
538 istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1;
539 break;
540 default:
541 if (namedmem != NULL) {
542 debug_step("pop");
543 pop:
544 inxt = initstk->i_next;
545 free(istk);
546 initstk = inxt;
547 goto again;
548 }
549 istk->i_remaining = 1;
550 break;
551 }
552
553 debug_initstack();
554 debug_leave();
555 }
556
557 static void
558 initstack_check_too_many(void)
559 {
560 istk_t *istk;
561
562 istk = initstk;
563
564 /*
565 * If a closing brace is expected we have at least one initializer
566 * too much.
567 */
568 if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) {
569 switch (istk->i_type->t_tspec) {
570 case ARRAY:
571 /* too many array initializers, expected %d */
572 error(173, istk->i_type->t_dim);
573 break;
574 case STRUCT:
575 case UNION:
576 /* too many struct/union initializers */
577 error(172);
578 break;
579 default:
580 /* too many initializers */
581 error(174);
582 break;
583 }
584 initerr = true;
585 }
586 }
587
588 static void
589 initstack_next_brace(void)
590 {
591
592 debug_enter();
593 debug_initstack();
594
595 if (initstk->i_type != NULL && is_scalar(initstk->i_type->t_tspec)) {
596 /* invalid initializer type %s */
597 error(176, type_name(initstk->i_type));
598 initerr = true;
599 }
600 if (!initerr)
601 initstack_check_too_many();
602 if (!initerr)
603 initstack_push();
604 if (!initerr) {
605 initstk->i_brace = true;
606 debug_step("%p %s", namedmem, type_name(
607 initstk->i_type != NULL ? initstk->i_type
608 : initstk->i_subt));
609 }
610
611 debug_initstack();
612 debug_leave();
613 }
614
615 static void
616 initstack_next_nobrace(void)
617 {
618 debug_enter();
619 debug_initstack();
620
621 if (initstk->i_type == NULL && !is_scalar(initstk->i_subt->t_tspec)) {
622 /* {}-enclosed initializer required */
623 error(181);
624 }
625
626 /*
627 * Make sure an entry with a scalar type is at the top of the stack.
628 *
629 * FIXME: Since C99 an initializer for an object with automatic
630 * storage need not be a constant expression anymore. It is
631 * perfectly fine to initialize a struct with a struct expression,
632 * see d_struct_init_nested.c for a demonstration.
633 */
634 if (!initerr)
635 initstack_check_too_many();
636 while (!initerr) {
637 if ((initstk->i_type != NULL &&
638 is_scalar(initstk->i_type->t_tspec)))
639 break;
640 initstack_push();
641 }
642
643 debug_initstack();
644 debug_leave();
645 }
646
647 void
648 init_lbrace(void)
649 {
650 if (initerr)
651 return;
652
653 debug_enter();
654 debug_initstack();
655
656 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
657 initstk->i_next == NULL) {
658 if (tflag && !is_scalar(initstk->i_subt->t_tspec))
659 /* no automatic aggregate initialization in trad. C */
660 warning(188);
661 }
662
663 /*
664 * Remove all entries which cannot be used for further initializers
665 * and do not expect a closing brace.
666 */
667 initstack_pop_nobrace();
668
669 initstack_next_brace();
670
671 debug_initstack();
672 debug_leave();
673 }
674
675 void
676 init_rbrace(void)
677 {
678 if (initerr)
679 return;
680
681 debug_enter();
682 debug_initstack();
683
684 initstack_pop_brace();
685
686 debug_initstack();
687 debug_leave();
688 }
689
690 void
691 init_using_expr(tnode_t *tn)
692 {
693 ptrdiff_t offs;
694 sym_t *sym;
695 tspec_t lt, rt;
696 tnode_t *ln;
697 struct mbl *tmem;
698 scl_t sc;
699
700 debug_enter();
701 debug_named_member();
702 debug_node(tn);
703 debug_initstack();
704
705 if (initerr || tn == NULL) {
706 debug_leave();
707 return;
708 }
709
710 sc = initsym->s_scl;
711
712 /*
713 * Do not test for automatic aggregate initialisation. If the
714 * initializer starts with a brace we have the warning already.
715 * If not, an error will be printed that the initializer must
716 * be enclosed by braces.
717 */
718
719 /*
720 * Local initialisation of non-array-types with only one expression
721 * without braces is done by ASSIGN
722 */
723 if ((sc == AUTO || sc == REG) &&
724 initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) {
725 ln = new_name_node(initsym, 0);
726 ln->tn_type = tduptyp(ln->tn_type);
727 ln->tn_type->t_const = false;
728 tn = build(ASSIGN, ln, tn);
729 expr(tn, false, false, false, false);
730 debug_initstack();
731 debug_leave();
732 return;
733 }
734
735 /*
736 * Remove all entries which cannot be used for further initializers
737 * and do not require a closing brace.
738 */
739 initstack_pop_nobrace();
740
741 /* Initialisations by strings are done in initstack_string(). */
742 if (initstack_string(tn)) {
743 debug_initstack();
744 debug_leave();
745 return;
746 }
747
748 initstack_next_nobrace();
749 if (initerr || tn == NULL) {
750 debug_initstack();
751 debug_leave();
752 return;
753 }
754
755 initstk->i_remaining--;
756 debug_step("remaining=%d tn=%p", initstk->i_remaining, tn);
757 /* Create a temporary node for the left side. */
758 ln = tgetblk(sizeof (tnode_t));
759 ln->tn_op = NAME;
760 ln->tn_type = tduptyp(initstk->i_type);
761 ln->tn_type->t_const = false;
762 ln->tn_lvalue = true;
763 ln->tn_sym = initsym; /* better than nothing */
764
765 tn = cconv(tn);
766
767 lt = ln->tn_type->t_tspec;
768 rt = tn->tn_type->t_tspec;
769
770 lint_assert(is_scalar(lt));
771
772 if (!typeok(INIT, 0, ln, tn)) {
773 debug_initstack();
774 debug_leave();
775 return;
776 }
777
778 /*
779 * Store the tree memory. This is necessary because otherwise
780 * expr() would free it.
781 */
782 tmem = tsave();
783 expr(tn, true, false, true, false);
784 trestor(tmem);
785
786 if (is_integer(lt) && ln->tn_type->t_bitfield && !is_integer(rt)) {
787 /*
788 * Bit-fields can be initialized in trad. C only by integer
789 * constants.
790 */
791 if (tflag)
792 /* bit-field initialisation is illegal in trad. C */
793 warning(186);
794 }
795
796 if (lt != rt || (initstk->i_type->t_bitfield && tn->tn_op == CON))
797 tn = convert(INIT, 0, initstk->i_type, tn);
798
799 if (tn != NULL && tn->tn_op != CON) {
800 sym = NULL;
801 offs = 0;
802 if (!constant_addr(tn, &sym, &offs)) {
803 if (sc == AUTO || sc == REG) {
804 /* non-constant initializer */
805 c99ism(177);
806 } else {
807 /* non-constant initializer */
808 error(177);
809 }
810 }
811 }
812
813 debug_initstack();
814 debug_leave();
815 }
816
817
818 static bool
819 initstack_string(tnode_t *tn)
820 {
821 tspec_t t;
822 istk_t *istk;
823 int len;
824 strg_t *strg;
825
826 if (tn->tn_op != STRING)
827 return false;
828
829 debug_enter();
830 debug_initstack();
831
832 istk = initstk;
833 strg = tn->tn_string;
834
835 /*
836 * Check if we have an array type which can be initialized by
837 * the string.
838 */
839 if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
840 debug_step("subt array");
841 t = istk->i_subt->t_subt->t_tspec;
842 if (!((strg->st_tspec == CHAR &&
843 (t == CHAR || t == UCHAR || t == SCHAR)) ||
844 (strg->st_tspec == WCHAR && t == WCHAR))) {
845 debug_leave();
846 return false;
847 }
848 /* Put the array at top of stack */
849 initstack_push();
850 istk = initstk;
851 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
852 debug_step("type array");
853 t = istk->i_type->t_subt->t_tspec;
854 if (!((strg->st_tspec == CHAR &&
855 (t == CHAR || t == UCHAR || t == SCHAR)) ||
856 (strg->st_tspec == WCHAR && t == WCHAR))) {
857 debug_leave();
858 return false;
859 }
860 /*
861 * If the array is already partly initialized, we are
862 * wrong here.
863 */
864 if (istk->i_remaining != istk->i_type->t_dim)
865 debug_leave();
866 return false;
867 } else {
868 debug_leave();
869 return false;
870 }
871
872 /* Get length without trailing NUL character. */
873 len = strg->st_len;
874
875 if (istk->i_nolimit) {
876 istk->i_nolimit = false;
877 istk->i_type->t_dim = len + 1;
878 setcomplete(istk->i_type, true);
879 } else {
880 if (istk->i_type->t_dim < len) {
881 /* non-null byte ignored in string initializer */
882 warning(187);
883 }
884 }
885
886 /* In every case the array is initialized completely. */
887 istk->i_remaining = 0;
888
889 debug_initstack();
890 debug_leave();
891 return true;
892 }
893