| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.177 2021/03/29 21:09:21 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.178 2021/03/29 21:34:17 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. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
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.177 2021/03/29 21:09:21 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.178 2021/03/29 21:34:17 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <string.h> | | 44 | #include <string.h> |
45 | | | 45 | |
46 | #include "lint1.h" | | 46 | #include "lint1.h" |
47 | | | 47 | |
48 | | | 48 | |
49 | /* | | 49 | /* |
50 | * Initialization | | 50 | * Initialization |
51 | * | | 51 | * |
52 | * Handles initializations of global or local objects, like in: | | 52 | * Handles initializations of global or local objects, like in: |
53 | * | | 53 | * |
| @@ -532,271 +532,271 @@ designation_shift_level(struct designati | | | @@ -532,271 +532,271 @@ designation_shift_level(struct designati |
532 | struct designator *head = dn->dn_head; | | 532 | struct designator *head = dn->dn_head; |
533 | dn->dn_head = dn->dn_head->dr_next; | | 533 | dn->dn_head = dn->dn_head->dr_next; |
534 | designator_free(head); | | 534 | designator_free(head); |
535 | } | | 535 | } |
536 | | | 536 | |
537 | designation_debug(dn); | | 537 | designation_debug(dn); |
538 | } | | 538 | } |
539 | | | 539 | |
540 | | | 540 | |
541 | static struct brace_level * | | 541 | static struct brace_level * |
542 | brace_level_new(type_t *type, type_t *subtype, int remaining, | | 542 | brace_level_new(type_t *type, type_t *subtype, int remaining, |
543 | struct brace_level *enclosing) | | 543 | struct brace_level *enclosing) |
544 | { | | 544 | { |
545 | struct brace_level *level = xcalloc(1, sizeof(*level)); | | 545 | struct brace_level *bl = xcalloc(1, sizeof(*bl)); |
546 | | | 546 | |
547 | level->bl_type = type; | | 547 | bl->bl_type = type; |
548 | level->bl_subtype = subtype; | | 548 | bl->bl_subtype = subtype; |
549 | level->bl_remaining = remaining; | | 549 | bl->bl_remaining = remaining; |
550 | level->bl_enclosing = enclosing; | | 550 | bl->bl_enclosing = enclosing; |
551 | | | 551 | |
552 | return level; | | 552 | return bl; |
553 | } | | 553 | } |
554 | | | 554 | |
555 | static void | | 555 | static void |
556 | brace_level_free(struct brace_level *level) | | 556 | brace_level_free(struct brace_level *bl) |
557 | { | | 557 | { |
558 | free(level); | | 558 | free(bl); |
559 | } | | 559 | } |
560 | | | 560 | |
561 | #ifdef DEBUG | | 561 | #ifdef DEBUG |
562 | /* | | 562 | /* |
563 | * TODO: only log the top of the stack after each modifying operation | | 563 | * TODO: only log the top of the stack after each modifying operation |
564 | * | | 564 | * |
565 | * TODO: wrap all write accesses to brace_level in setter functions | | 565 | * TODO: wrap all write accesses to brace_level in setter functions |
566 | */ | | 566 | */ |
567 | static void | | 567 | static void |
568 | brace_level_debug(const struct brace_level *level) | | 568 | brace_level_debug(const struct brace_level *bl) |
569 | { | | 569 | { |
570 | if (level->bl_type != NULL) | | 570 | if (bl->bl_type != NULL) |
571 | debug_printf("type '%s'", type_name(level->bl_type)); | | 571 | debug_printf("type '%s'", type_name(bl->bl_type)); |
572 | if (level->bl_type != NULL && level->bl_subtype != NULL) | | 572 | if (bl->bl_type != NULL && bl->bl_subtype != NULL) |
573 | debug_printf(", "); | | 573 | debug_printf(", "); |
574 | if (level->bl_subtype != NULL) | | 574 | if (bl->bl_subtype != NULL) |
575 | debug_printf("subtype '%s'", type_name(level->bl_subtype)); | | 575 | debug_printf("subtype '%s'", type_name(bl->bl_subtype)); |
576 | | | 576 | |
577 | if (level->bl_brace) | | 577 | if (bl->bl_brace) |
578 | debug_printf(", needs closing brace"); | | 578 | debug_printf(", needs closing brace"); |
579 | if (level->bl_array_of_unknown_size) | | 579 | if (bl->bl_array_of_unknown_size) |
580 | debug_printf(", array of unknown size"); | | 580 | debug_printf(", array of unknown size"); |
581 | if (level->bl_seen_named_member) | | 581 | if (bl->bl_seen_named_member) |
582 | debug_printf(", seen named member"); | | 582 | debug_printf(", seen named member"); |
583 | | | 583 | |
584 | const type_t *eff_type = level->bl_type != NULL | | 584 | const type_t *eff_type = bl->bl_type != NULL |
585 | ? level->bl_type : level->bl_subtype; | | 585 | ? bl->bl_type : bl->bl_subtype; |
586 | if (eff_type->t_tspec == STRUCT && level->bl_next_member != NULL) | | 586 | if (eff_type->t_tspec == STRUCT && bl->bl_next_member != NULL) |
587 | debug_printf(", next member '%s'", | | 587 | debug_printf(", next member '%s'", |
588 | level->bl_next_member->s_name); | | 588 | bl->bl_next_member->s_name); |
589 | | | 589 | |
590 | debug_printf(", remaining %d\n", level->bl_remaining); | | 590 | debug_printf(", remaining %d\n", bl->bl_remaining); |
591 | } | | 591 | } |
592 | #else | | 592 | #else |
593 | #define brace_level_debug(level) do { } while (false) | | 593 | #define brace_level_debug(bl) do { } while (false) |
594 | #endif | | 594 | #endif |
595 | | | 595 | |
596 | static void | | 596 | static void |
597 | brace_level_assert_struct_or_union(const struct brace_level *level) | | 597 | brace_level_assert_struct_or_union(const struct brace_level *bl) |
598 | { | | 598 | { |
599 | lint_assert(is_struct_or_union(level->bl_type->t_tspec)); | | 599 | lint_assert(is_struct_or_union(bl->bl_type->t_tspec)); |
600 | } | | 600 | } |
601 | | | 601 | |
602 | static void | | 602 | static void |
603 | brace_level_assert_array(const struct brace_level *level) | | 603 | brace_level_assert_array(const struct brace_level *bl) |
604 | { | | 604 | { |
605 | lint_assert(level->bl_type->t_tspec == ARRAY); | | 605 | lint_assert(bl->bl_type->t_tspec == ARRAY); |
606 | } | | 606 | } |
607 | | | 607 | |
608 | static type_t * | | 608 | static type_t * |
609 | brace_level_subtype(struct brace_level *level) | | 609 | brace_level_subtype(struct brace_level *bl) |
610 | { | | 610 | { |
611 | | | 611 | |
612 | if (level->bl_subtype != NULL) | | 612 | if (bl->bl_subtype != NULL) |
613 | return level->bl_subtype; | | 613 | return bl->bl_subtype; |
614 | | | 614 | |
615 | return level->bl_type; | | 615 | return bl->bl_type; |
616 | } | | 616 | } |
617 | | | 617 | |
618 | static void | | 618 | static void |
619 | brace_level_set_array_dimension(struct brace_level *level, int dim) | | 619 | brace_level_set_array_dimension(struct brace_level *bl, int dim) |
620 | { | | 620 | { |
621 | brace_level_assert_array(level); | | 621 | brace_level_assert_array(bl); |
622 | | | 622 | |
623 | debug_step("setting the array size to %d", dim); | | 623 | debug_step("setting the array size to %d", dim); |
624 | level->bl_type->t_dim = dim; | | 624 | bl->bl_type->t_dim = dim; |
625 | debug_indent(); | | 625 | debug_indent(); |
626 | brace_level_debug(level); | | 626 | brace_level_debug(bl); |
627 | } | | 627 | } |
628 | | | 628 | |
629 | static void | | 629 | static void |
630 | brace_level_next_member(struct brace_level *level) | | 630 | brace_level_next_member(struct brace_level *bl) |
631 | { | | 631 | { |
632 | const sym_t *m; | | 632 | const sym_t *m; |
633 | | | 633 | |
634 | brace_level_assert_struct_or_union(level); | | 634 | brace_level_assert_struct_or_union(bl); |
635 | do { | | 635 | do { |
636 | m = level->bl_next_member = level->bl_next_member->s_next; | | 636 | m = bl->bl_next_member = bl->bl_next_member->s_next; |
637 | /* XXX: can this assertion be made to fail? */ | | 637 | /* XXX: can this assertion be made to fail? */ |
638 | lint_assert(m != NULL); | | 638 | lint_assert(m != NULL); |
639 | } while (m->s_bitfield && m->s_name == unnamed); | | 639 | } while (m->s_bitfield && m->s_name == unnamed); |
640 | | | 640 | |
641 | debug_indent(); | | 641 | debug_indent(); |
642 | brace_level_debug(level); | | 642 | brace_level_debug(bl); |
643 | } | | 643 | } |
644 | | | 644 | |
645 | static const sym_t * | | 645 | static const sym_t * |
646 | brace_level_look_up_member(const struct brace_level *level, const char *name) | | 646 | brace_level_look_up_member(const struct brace_level *bl, const char *name) |
647 | { | | 647 | { |
648 | | | 648 | |
649 | brace_level_assert_struct_or_union(level); | | 649 | brace_level_assert_struct_or_union(bl); |
650 | return look_up_member(level->bl_type->t_str->sou_first_member, name); | | 650 | return look_up_member(bl->bl_type->t_str->sou_first_member, name); |
651 | } | | 651 | } |
652 | | | 652 | |
653 | static sym_t * | | 653 | static sym_t * |
654 | brace_level_look_up_first_member_named(struct brace_level *level, | | 654 | brace_level_look_up_first_member_named(struct brace_level *bl, |
655 | const char *name, int *count) | | 655 | const char *name, int *count) |
656 | { | | 656 | { |
657 | sym_t *m; | | 657 | sym_t *m; |
658 | | | 658 | |
659 | for (m = level->bl_type->t_str->sou_first_member; | | 659 | for (m = bl->bl_type->t_str->sou_first_member; |
660 | m != NULL; m = m->s_next) { | | 660 | m != NULL; m = m->s_next) { |
661 | if (is_unnamed_member(m)) | | 661 | if (is_unnamed_member(m)) |
662 | continue; | | 662 | continue; |
663 | if (strcmp(m->s_name, name) != 0) | | 663 | if (strcmp(m->s_name, name) != 0) |
664 | continue; | | 664 | continue; |
665 | (*count)++; | | 665 | (*count)++; |
666 | break; | | 666 | break; |
667 | } | | 667 | } |
668 | | | 668 | |
669 | return m; | | 669 | return m; |
670 | } | | 670 | } |
671 | | | 671 | |
672 | static sym_t * | | 672 | static sym_t * |
673 | brace_level_look_up_first_member_unnamed(struct brace_level *level, int *count) | | 673 | brace_level_look_up_first_member_unnamed(struct brace_level *bl, int *count) |
674 | { | | 674 | { |
675 | sym_t *m; | | 675 | sym_t *m; |
676 | | | 676 | |
677 | brace_level_assert_struct_or_union(level); | | 677 | brace_level_assert_struct_or_union(bl); |
678 | | | 678 | |
679 | for (m = level->bl_type->t_str->sou_first_member; | | 679 | for (m = bl->bl_type->t_str->sou_first_member; |
680 | m != NULL; m = m->s_next) { | | 680 | m != NULL; m = m->s_next) { |
681 | if (is_unnamed_member(m)) | | 681 | if (is_unnamed_member(m)) |
682 | continue; | | 682 | continue; |
683 | /* XXX: What is this code for? */ | | 683 | /* XXX: What is this code for? */ |
684 | if (++(*count) == 1) { | | 684 | if (++(*count) == 1) { |
685 | level->bl_next_member = m; | | 685 | bl->bl_next_member = m; |
686 | level->bl_subtype = m->s_type; | | 686 | bl->bl_subtype = m->s_type; |
687 | } | | 687 | } |
688 | } | | 688 | } |
689 | | | 689 | |
690 | return m; | | 690 | return m; |
691 | } | | 691 | } |
692 | | | 692 | |
693 | /* TODO: document me */ | | 693 | /* TODO: document me */ |
694 | /* TODO: think of a better name than 'push' */ | | 694 | /* TODO: think of a better name than 'push' */ |
695 | static bool | | 695 | static bool |
696 | brace_level_push_array(struct brace_level *level) | | 696 | brace_level_push_array(struct brace_level *bl) |
697 | { | | 697 | { |
698 | brace_level_assert_array(level); | | 698 | brace_level_assert_array(bl); |
699 | | | 699 | |
700 | if (level->bl_enclosing->bl_seen_named_member) { | | 700 | if (bl->bl_enclosing->bl_seen_named_member) { |
701 | level->bl_brace = true; | | 701 | bl->bl_brace = true; |
702 | debug_step("ARRAY, seen named member, needs closing brace"); | | 702 | debug_step("ARRAY, seen named member, needs closing brace"); |
703 | } | | 703 | } |
704 | | | 704 | |
705 | if (is_incomplete(level->bl_type) && | | 705 | if (is_incomplete(bl->bl_type) && |
706 | level->bl_enclosing->bl_enclosing != NULL) { | | 706 | bl->bl_enclosing->bl_enclosing != NULL) { |
707 | /* initialization of an incomplete type */ | | 707 | /* initialization of an incomplete type */ |
708 | error(175); | | 708 | error(175); |
709 | return false; | | 709 | return false; |
710 | } | | 710 | } |
711 | | | 711 | |
712 | level->bl_subtype = level->bl_type->t_subt; | | 712 | bl->bl_subtype = bl->bl_type->t_subt; |
713 | level->bl_array_of_unknown_size = is_incomplete(level->bl_type); | | 713 | bl->bl_array_of_unknown_size = is_incomplete(bl->bl_type); |
714 | level->bl_remaining = level->bl_type->t_dim; | | 714 | bl->bl_remaining = bl->bl_type->t_dim; |
715 | debug_step("type '%s' remaining %d", | | 715 | debug_step("type '%s' remaining %d", |
716 | type_name(level->bl_type), level->bl_remaining); | | 716 | type_name(bl->bl_type), bl->bl_remaining); |
717 | return true; | | 717 | return true; |
718 | } | | 718 | } |
719 | | | 719 | |
720 | /* | | 720 | /* |
721 | * If the removed element was a structure member, we must go | | 721 | * If the removed element was a structure member, we must go |
722 | * to the next structure member. | | 722 | * to the next structure member. |
723 | * | | 723 | * |
724 | * XXX: Nothing should ever be "removed" at this point. | | 724 | * XXX: Nothing should ever be "removed" at this point. |
725 | * | | 725 | * |
726 | * TODO: think of a better name than 'pop' | | 726 | * TODO: think of a better name than 'pop' |
727 | */ | | 727 | */ |
728 | static void | | 728 | static void |
729 | brace_level_pop_item_unnamed(struct brace_level *level) | | 729 | brace_level_pop_item_unnamed(struct brace_level *bl) |
730 | { | | 730 | { |
731 | if (level->bl_remaining > 0 && level->bl_type->t_tspec == STRUCT && | | 731 | if (bl->bl_remaining > 0 && bl->bl_type->t_tspec == STRUCT && |
732 | !level->bl_seen_named_member) { | | 732 | !bl->bl_seen_named_member) { |
733 | brace_level_next_member(level); | | 733 | brace_level_next_member(bl); |
734 | level->bl_subtype = level->bl_next_member->s_type; | | 734 | bl->bl_subtype = bl->bl_next_member->s_type; |
735 | } | | 735 | } |
736 | } | | 736 | } |
737 | | | 737 | |
738 | static bool | | 738 | static bool |
739 | brace_level_check_too_many_initializers(struct brace_level *level) | | 739 | brace_level_check_too_many_initializers(struct brace_level *bl) |
740 | { | | 740 | { |
741 | if (level->bl_remaining > 0) | | 741 | if (bl->bl_remaining > 0) |
742 | return true; | | 742 | return true; |
743 | /* | | 743 | /* |
744 | * FIXME: even with named members, there can be too many initializers | | 744 | * FIXME: even with named members, there can be too many initializers |
745 | */ | | 745 | */ |
746 | if (level->bl_array_of_unknown_size || level->bl_seen_named_member) | | 746 | if (bl->bl_array_of_unknown_size || bl->bl_seen_named_member) |
747 | return true; | | 747 | return true; |
748 | | | 748 | |
749 | tspec_t t = level->bl_type->t_tspec; | | 749 | tspec_t t = bl->bl_type->t_tspec; |
750 | if (t == ARRAY) { | | 750 | if (t == ARRAY) { |
751 | /* too many array initializers, expected %d */ | | 751 | /* too many array initializers, expected %d */ |
752 | error(173, level->bl_type->t_dim); | | 752 | error(173, bl->bl_type->t_dim); |
753 | } else if (is_struct_or_union(t)) { | | 753 | } else if (is_struct_or_union(t)) { |
754 | /* too many struct/union initializers */ | | 754 | /* too many struct/union initializers */ |
755 | error(172); | | 755 | error(172); |
756 | } else { | | 756 | } else { |
757 | /* too many initializers */ | | 757 | /* too many initializers */ |
758 | error(174); | | 758 | error(174); |
759 | } | | 759 | } |
760 | return false; | | 760 | return false; |
761 | } | | 761 | } |
762 | | | 762 | |
763 | /* Extend an array of unknown size by one element */ | | 763 | /* Extend an array of unknown size by one element */ |
764 | static void | | 764 | static void |
765 | brace_level_extend_if_array_of_unknown_size(struct brace_level *level) | | 765 | brace_level_extend_if_array_of_unknown_size(struct brace_level *bl) |
766 | { | | 766 | { |
767 | | | 767 | |
768 | if (level->bl_remaining != 0) | | 768 | if (bl->bl_remaining != 0) |
769 | return; | | 769 | return; |
770 | /* | | 770 | /* |
771 | * XXX: According to the function name, there should be a 'return' if | | 771 | * XXX: According to the function name, there should be a 'return' if |
772 | * bl_array_of_unknown_size is false. There's probably a test missing | | 772 | * bl_array_of_unknown_size is false. There's probably a test missing |
773 | * for that case. | | 773 | * for that case. |
774 | */ | | 774 | */ |
775 | | | 775 | |
776 | /* | | 776 | /* |
777 | * The only place where an incomplete array may appear is at the | | 777 | * The only place where an incomplete array may appear is at the |
778 | * outermost aggregate level of the object to be initialized. | | 778 | * outermost aggregate bl of the object to be initialized. |
779 | */ | | 779 | */ |
780 | lint_assert(level->bl_enclosing->bl_enclosing == NULL); | | 780 | lint_assert(bl->bl_enclosing->bl_enclosing == NULL); |
781 | lint_assert(level->bl_type->t_tspec == ARRAY); | | 781 | lint_assert(bl->bl_type->t_tspec == ARRAY); |
782 | | | 782 | |
783 | debug_step("extending array of unknown size '%s'", | | 783 | debug_step("extending array of unknown size '%s'", |
784 | type_name(level->bl_type)); | | 784 | type_name(bl->bl_type)); |
785 | level->bl_remaining = 1; | | 785 | bl->bl_remaining = 1; |
786 | level->bl_type->t_dim++; | | 786 | bl->bl_type->t_dim++; |
787 | setcomplete(level->bl_type, true); | | 787 | setcomplete(bl->bl_type, true); |
788 | | | 788 | |
789 | debug_step("extended type is '%s'", type_name(level->bl_type)); | | 789 | debug_step("extended type is '%s'", type_name(bl->bl_type)); |
790 | } | | 790 | } |
791 | | | 791 | |
792 | | | 792 | |
793 | static struct initialization * | | 793 | static struct initialization * |
794 | initialization_new(sym_t *sym) | | 794 | initialization_new(sym_t *sym) |
795 | { | | 795 | { |
796 | struct initialization *in = xcalloc(1, sizeof(*in)); | | 796 | struct initialization *in = xcalloc(1, sizeof(*in)); |
797 | | | 797 | |
798 | in->in_sym = sym; | | 798 | in->in_sym = sym; |
799 | | | 799 | |
800 | return in; | | 800 | return in; |
801 | } | | 801 | } |
802 | | | 802 | |
| @@ -816,31 +816,31 @@ initialization_free(struct initializatio | | | @@ -816,31 +816,31 @@ initialization_free(struct initializatio |
816 | #ifdef DEBUG | | 816 | #ifdef DEBUG |
817 | /* | | 817 | /* |
818 | * TODO: only call debug_initstack after each push/pop. | | 818 | * TODO: only call debug_initstack after each push/pop. |
819 | */ | | 819 | */ |
820 | static void | | 820 | static void |
821 | initialization_debug(const struct initialization *in) | | 821 | initialization_debug(const struct initialization *in) |
822 | { | | 822 | { |
823 | if (in->in_brace_level == NULL) { | | 823 | if (in->in_brace_level == NULL) { |
824 | debug_step("no brace level in the current initialization"); | | 824 | debug_step("no brace level in the current initialization"); |
825 | return; | | 825 | return; |
826 | } | | 826 | } |
827 | | | 827 | |
828 | size_t i = 0; | | 828 | size_t i = 0; |
829 | for (const struct brace_level *level = in->in_brace_level; | | 829 | for (const struct brace_level *bl = in->in_brace_level; |
830 | level != NULL; level = level->bl_enclosing) { | | 830 | bl != NULL; bl = bl->bl_enclosing) { |
831 | debug_indent(); | | 831 | debug_indent(); |
832 | debug_printf("brace level %zu: ", i); | | 832 | debug_printf("brace level %zu: ", i); |
833 | brace_level_debug(level); | | 833 | brace_level_debug(bl); |
834 | i++; | | 834 | i++; |
835 | } | | 835 | } |
836 | } | | 836 | } |
837 | #else | | 837 | #else |
838 | #define initialization_debug(in) do { } while (false) | | 838 | #define initialization_debug(in) do { } while (false) |
839 | #endif | | 839 | #endif |
840 | | | 840 | |
841 | /* | | 841 | /* |
842 | * Initialize the initialization stack by putting an entry for the object | | 842 | * Initialize the initialization stack by putting an entry for the object |
843 | * which is to be initialized on it. | | 843 | * which is to be initialized on it. |
844 | * | | 844 | * |
845 | * TODO: merge into initialization_new if possible | | 845 | * TODO: merge into initialization_new if possible |
846 | */ | | 846 | */ |
| @@ -867,212 +867,212 @@ initialization_init(struct initializatio | | | @@ -867,212 +867,212 @@ initialization_init(struct initializatio |
867 | } | | 867 | } |
868 | | | 868 | |
869 | static void | | 869 | static void |
870 | initialization_set_error(struct initialization *in) | | 870 | initialization_set_error(struct initialization *in) |
871 | { | | 871 | { |
872 | in->in_err = true; | | 872 | in->in_err = true; |
873 | } | | 873 | } |
874 | | | 874 | |
875 | /* TODO: document me */ | | 875 | /* TODO: document me */ |
876 | /* TODO: think of a better name than 'push' */ | | 876 | /* TODO: think of a better name than 'push' */ |
877 | static bool | | 877 | static bool |
878 | initialization_push_struct_or_union(struct initialization *in) | | 878 | initialization_push_struct_or_union(struct initialization *in) |
879 | { | | 879 | { |
880 | struct brace_level *level = in->in_brace_level; | | 880 | struct brace_level *bl = in->in_brace_level; |
881 | int cnt; | | 881 | int cnt; |
882 | sym_t *m; | | 882 | sym_t *m; |
883 | | | 883 | |
884 | if (is_incomplete(level->bl_type)) { | | 884 | if (is_incomplete(bl->bl_type)) { |
885 | /* initialization of an incomplete type */ | | 885 | /* initialization of an incomplete type */ |
886 | error(175); | | 886 | error(175); |
887 | initialization_set_error(in); | | 887 | initialization_set_error(in); |
888 | return false; | | 888 | return false; |
889 | } | | 889 | } |
890 | | | 890 | |
891 | cnt = 0; | | 891 | cnt = 0; |
892 | designation_debug(&in->in_designation); | | 892 | designation_debug(&in->in_designation); |
893 | debug_step("lookup for '%s'%s", | | 893 | debug_step("lookup for '%s'%s", |
894 | type_name(level->bl_type), | | 894 | type_name(bl->bl_type), |
895 | level->bl_seen_named_member ? ", seen named member" : ""); | | 895 | bl->bl_seen_named_member ? ", seen named member" : ""); |
896 | | | 896 | |
897 | if (in->in_designation.dn_head != NULL) | | 897 | if (in->in_designation.dn_head != NULL) |
898 | m = brace_level_look_up_first_member_named(level, | | 898 | m = brace_level_look_up_first_member_named(bl, |
899 | in->in_designation.dn_head->dr_name, &cnt); | | 899 | in->in_designation.dn_head->dr_name, &cnt); |
900 | else | | 900 | else |
901 | m = brace_level_look_up_first_member_unnamed(level, &cnt); | | 901 | m = brace_level_look_up_first_member_unnamed(bl, &cnt); |
902 | | | 902 | |
903 | if (in->in_designation.dn_head != NULL) { | | 903 | if (in->in_designation.dn_head != NULL) { |
904 | if (m == NULL) { | | 904 | if (m == NULL) { |
905 | debug_step("pop struct"); | | 905 | debug_step("pop struct"); |
906 | return true; | | 906 | return true; |
907 | } | | 907 | } |
908 | level->bl_next_member = m; | | 908 | bl->bl_next_member = m; |
909 | level->bl_subtype = m->s_type; | | 909 | bl->bl_subtype = m->s_type; |
910 | level->bl_seen_named_member = true; | | 910 | bl->bl_seen_named_member = true; |
911 | debug_step("named member '%s'", | | 911 | debug_step("named member '%s'", |
912 | in->in_designation.dn_head->dr_name); | | 912 | in->in_designation.dn_head->dr_name); |
913 | designation_shift_level(&in->in_designation); | | 913 | designation_shift_level(&in->in_designation); |
914 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; | | 914 | cnt = bl->bl_type->t_tspec == STRUCT ? 2 : 1; |
915 | } | | 915 | } |
916 | level->bl_brace = true; | | 916 | bl->bl_brace = true; |
917 | debug_step("unnamed element with type '%s'%s", | | 917 | debug_step("unnamed element with type '%s'%s", |
918 | type_name( | | 918 | type_name( |
919 | level->bl_type != NULL ? level->bl_type : level->bl_subtype), | | 919 | bl->bl_type != NULL ? bl->bl_type : bl->bl_subtype), |
920 | level->bl_brace ? ", needs closing brace" : ""); | | 920 | bl->bl_brace ? ", needs closing brace" : ""); |
921 | if (cnt == 0) { | | 921 | if (cnt == 0) { |
922 | /* cannot init. struct/union with no named member */ | | 922 | /* cannot init. struct/union with no named member */ |
923 | error(179); | | 923 | error(179); |
924 | initialization_set_error(in); | | 924 | initialization_set_error(in); |
925 | return false; | | 925 | return false; |
926 | } | | 926 | } |
927 | level->bl_remaining = level->bl_type->t_tspec == STRUCT ? cnt : 1; | | 927 | bl->bl_remaining = bl->bl_type->t_tspec == STRUCT ? cnt : 1; |
928 | return false; | | 928 | return false; |
929 | } | | 929 | } |
930 | | | 930 | |
931 | static void | | 931 | static void |
932 | initialization_end_brace_level(struct initialization *in) | | 932 | initialization_end_brace_level(struct initialization *in) |
933 | { | | 933 | { |
934 | struct brace_level *level = in->in_brace_level; | | 934 | struct brace_level *bl = in->in_brace_level; |
935 | in->in_brace_level = level->bl_enclosing; | | 935 | in->in_brace_level = bl->bl_enclosing; |
936 | brace_level_free(level); | | 936 | brace_level_free(bl); |
937 | } | | 937 | } |
938 | | | 938 | |
939 | /* TODO: document me */ | | 939 | /* TODO: document me */ |
940 | /* TODO: think of a better name than 'push' */ | | 940 | /* TODO: think of a better name than 'push' */ |
941 | static void | | 941 | static void |
942 | initialization_push(struct initialization *in) | | 942 | initialization_push(struct initialization *in) |
943 | { | | 943 | { |
944 | struct brace_level *level; | | 944 | struct brace_level *bl; |
945 | | | 945 | |
946 | debug_enter(); | | 946 | debug_enter(); |
947 | | | 947 | |
948 | brace_level_extend_if_array_of_unknown_size(in->in_brace_level); | | 948 | brace_level_extend_if_array_of_unknown_size(in->in_brace_level); |
949 | | | 949 | |
950 | level = in->in_brace_level; | | 950 | bl = in->in_brace_level; |
951 | lint_assert(level->bl_remaining > 0); | | 951 | lint_assert(bl->bl_remaining > 0); |
952 | | | 952 | |
953 | in->in_brace_level = brace_level_new(brace_level_subtype(level), NULL, 0, | | 953 | in->in_brace_level = brace_level_new(brace_level_subtype(bl), NULL, 0, |
954 | level); | | 954 | bl); |
955 | lint_assert(in->in_brace_level->bl_type != NULL); | | 955 | lint_assert(in->in_brace_level->bl_type != NULL); |
956 | lint_assert(in->in_brace_level->bl_type->t_tspec != FUNC); | | 956 | lint_assert(in->in_brace_level->bl_type->t_tspec != FUNC); |
957 | | | 957 | |
958 | again: | | 958 | again: |
959 | level = in->in_brace_level; | | 959 | bl = in->in_brace_level; |
960 | | | 960 | |
961 | debug_step("expecting type '%s'", type_name(level->bl_type)); | | 961 | debug_step("expecting type '%s'", type_name(bl->bl_type)); |
962 | lint_assert(level->bl_type != NULL); | | 962 | lint_assert(bl->bl_type != NULL); |
963 | switch (level->bl_type->t_tspec) { | | 963 | switch (bl->bl_type->t_tspec) { |
964 | case ARRAY: | | 964 | case ARRAY: |
965 | if (in->in_designation.dn_head != NULL) { | | 965 | if (in->in_designation.dn_head != NULL) { |
966 | debug_step("pop array, named member '%s'%s", | | 966 | debug_step("pop array, named member '%s'%s", |
967 | in->in_designation.dn_head->dr_name, | | 967 | in->in_designation.dn_head->dr_name, |
968 | level->bl_brace ? ", needs closing brace" : ""); | | 968 | bl->bl_brace ? ", needs closing brace" : ""); |
969 | goto pop; | | 969 | goto pop; |
970 | } | | 970 | } |
971 | | | 971 | |
972 | if (!brace_level_push_array(level)) | | 972 | if (!brace_level_push_array(bl)) |
973 | initialization_set_error(in); | | 973 | initialization_set_error(in); |
974 | break; | | 974 | break; |
975 | | | 975 | |
976 | case UNION: | | 976 | case UNION: |
977 | if (tflag) | | 977 | if (tflag) |
978 | /* initialization of union is illegal in trad. C */ | | 978 | /* initialization of union is illegal in trad. C */ |
979 | warning(238); | | 979 | warning(238); |
980 | /* FALLTHROUGH */ | | 980 | /* FALLTHROUGH */ |
981 | case STRUCT: | | 981 | case STRUCT: |
982 | if (initialization_push_struct_or_union(in)) | | 982 | if (initialization_push_struct_or_union(in)) |
983 | goto pop; | | 983 | goto pop; |
984 | break; | | 984 | break; |
985 | default: | | 985 | default: |
986 | if (in->in_designation.dn_head != NULL) { | | 986 | if (in->in_designation.dn_head != NULL) { |
987 | debug_step("pop scalar"); | | 987 | debug_step("pop scalar"); |
988 | pop: | | 988 | pop: |
989 | initialization_end_brace_level(in); | | 989 | initialization_end_brace_level(in); |
990 | goto again; | | 990 | goto again; |
991 | } | | 991 | } |
992 | /* The initialization stack now expects a single scalar. */ | | 992 | /* The initialization stack now expects a single scalar. */ |
993 | level->bl_remaining = 1; | | 993 | bl->bl_remaining = 1; |
994 | break; | | 994 | break; |
995 | } | | 995 | } |
996 | | | 996 | |
997 | initialization_debug(in); | | 997 | initialization_debug(in); |
998 | debug_leave(); | | 998 | debug_leave(); |
999 | } | | 999 | } |
1000 | | | 1000 | |
1001 | /* TODO: document me */ | | 1001 | /* TODO: document me */ |
1002 | static void | | 1002 | static void |
1003 | initialization_pop_item_named(struct initialization *in, const char *name) | | 1003 | initialization_pop_item_named(struct initialization *in, const char *name) |
1004 | { | | 1004 | { |
1005 | struct brace_level *level = in->in_brace_level; | | 1005 | struct brace_level *bl = in->in_brace_level; |
1006 | const sym_t *m; | | 1006 | const sym_t *m; |
1007 | | | 1007 | |
1008 | /* | | 1008 | /* |
1009 | * TODO: fix wording of the debug message; this doesn't seem to be | | 1009 | * TODO: fix wording of the debug message; this doesn't seem to be |
1010 | * related to initializing the named member. | | 1010 | * related to initializing the named member. |
1011 | */ | | 1011 | */ |
1012 | debug_step("initializing named member '%s'", name); | | 1012 | debug_step("initializing named member '%s'", name); |
1013 | | | 1013 | |
1014 | if (!is_struct_or_union(level->bl_type->t_tspec)) { | | 1014 | if (!is_struct_or_union(bl->bl_type->t_tspec)) { |
1015 | /* syntax error '%s' */ | | 1015 | /* syntax error '%s' */ |
1016 | error(249, "named member must only be used with struct/union"); | | 1016 | error(249, "named member must only be used with struct/union"); |
1017 | initialization_set_error(in); | | 1017 | initialization_set_error(in); |
1018 | return; | | 1018 | return; |
1019 | } | | 1019 | } |
1020 | | | 1020 | |
1021 | m = brace_level_look_up_member(level, name); | | 1021 | m = brace_level_look_up_member(bl, name); |
1022 | if (m == NULL) { | | 1022 | if (m == NULL) { |
1023 | /* TODO: add type information to the message */ | | 1023 | /* TODO: add type information to the message */ |
1024 | /* undefined struct/union member: %s */ | | 1024 | /* undefined struct/union member: %s */ |
1025 | error(101, name); | | 1025 | error(101, name); |
1026 | | | 1026 | |
1027 | designation_shift_level(&in->in_designation); | | 1027 | designation_shift_level(&in->in_designation); |
1028 | level->bl_seen_named_member = true; | | 1028 | bl->bl_seen_named_member = true; |
1029 | return; | | 1029 | return; |
1030 | } | | 1030 | } |
1031 | | | 1031 | |
1032 | debug_step("found matching member"); | | 1032 | debug_step("found matching member"); |
1033 | level->bl_subtype = m->s_type; | | 1033 | bl->bl_subtype = m->s_type; |
1034 | /* XXX: why ++? */ | | 1034 | /* XXX: why ++? */ |
1035 | level->bl_remaining++; | | 1035 | bl->bl_remaining++; |
1036 | /* XXX: why is bl_seen_named_member not set? */ | | 1036 | /* XXX: why is bl_seen_named_member not set? */ |
1037 | designation_shift_level(&in->in_designation); | | 1037 | designation_shift_level(&in->in_designation); |
1038 | } | | 1038 | } |
1039 | | | 1039 | |
1040 | /* TODO: think of a better name than 'pop' */ | | 1040 | /* TODO: think of a better name than 'pop' */ |
1041 | static void | | 1041 | static void |
1042 | initialization_pop_item(struct initialization *in) | | 1042 | initialization_pop_item(struct initialization *in) |
1043 | { | | 1043 | { |
1044 | struct brace_level *level; | | 1044 | struct brace_level *bl; |
1045 | | | 1045 | |
1046 | debug_enter(); | | 1046 | debug_enter(); |
1047 | | | 1047 | |
1048 | level = in->in_brace_level; | | 1048 | bl = in->in_brace_level; |
1049 | debug_indent(); | | 1049 | debug_indent(); |
1050 | debug_printf("popping: "); | | 1050 | debug_printf("popping: "); |
1051 | brace_level_debug(level); | | 1051 | brace_level_debug(bl); |
1052 | | | 1052 | |
1053 | in->in_brace_level = level->bl_enclosing; | | 1053 | in->in_brace_level = bl->bl_enclosing; |
1054 | brace_level_free(level); | | 1054 | brace_level_free(bl); |
1055 | level = in->in_brace_level; | | 1055 | bl = in->in_brace_level; |
1056 | lint_assert(level != NULL); | | 1056 | lint_assert(bl != NULL); |
1057 | | | 1057 | |
1058 | level->bl_remaining--; | | 1058 | bl->bl_remaining--; |
1059 | lint_assert(level->bl_remaining >= 0); | | 1059 | lint_assert(bl->bl_remaining >= 0); |
1060 | debug_step("%d elements remaining", level->bl_remaining); | | 1060 | debug_step("%d elements remaining", bl->bl_remaining); |
1061 | | | 1061 | |
1062 | if (in->in_designation.dn_head != NULL && in->in_designation.dn_head->dr_name != NULL) | | 1062 | if (in->in_designation.dn_head != NULL && in->in_designation.dn_head->dr_name != NULL) |
1063 | initialization_pop_item_named(in, in->in_designation.dn_head->dr_name); | | 1063 | initialization_pop_item_named(in, in->in_designation.dn_head->dr_name); |
1064 | else | | 1064 | else |
1065 | brace_level_pop_item_unnamed(level); | | 1065 | brace_level_pop_item_unnamed(bl); |
1066 | | | 1066 | |
1067 | initialization_debug(in); | | 1067 | initialization_debug(in); |
1068 | debug_leave(); | | 1068 | debug_leave(); |
1069 | } | | 1069 | } |
1070 | | | 1070 | |
1071 | /* | | 1071 | /* |
1072 | * Take all entries which cannot be used for further initializers from the | | 1072 | * Take all entries which cannot be used for further initializers from the |
1073 | * stack, but do this only if they do not require a closing brace. | | 1073 | * stack, but do this only if they do not require a closing brace. |
1074 | */ | | 1074 | */ |
1075 | /* TODO: think of a better name than 'pop' */ | | 1075 | /* TODO: think of a better name than 'pop' */ |
1076 | static void | | 1076 | static void |
1077 | initialization_pop_nobrace(struct initialization *in) | | 1077 | initialization_pop_nobrace(struct initialization *in) |
1078 | { | | 1078 | { |
| @@ -1107,35 +1107,35 @@ initialization_next_brace(struct initial | | | @@ -1107,35 +1107,35 @@ initialization_next_brace(struct initial |
1107 | if (!in->in_err) { | | 1107 | if (!in->in_err) { |
1108 | in->in_brace_level->bl_brace = true; | | 1108 | in->in_brace_level->bl_brace = true; |
1109 | designation_debug(&in->in_designation); | | 1109 | designation_debug(&in->in_designation); |
1110 | if (in->in_brace_level->bl_type != NULL) | | 1110 | if (in->in_brace_level->bl_type != NULL) |
1111 | debug_step("expecting type '%s'", | | 1111 | debug_step("expecting type '%s'", |
1112 | type_name(in->in_brace_level->bl_type)); | | 1112 | type_name(in->in_brace_level->bl_type)); |
1113 | } | | 1113 | } |
1114 | | | 1114 | |
1115 | initialization_debug(in); | | 1115 | initialization_debug(in); |
1116 | debug_leave(); | | 1116 | debug_leave(); |
1117 | } | | 1117 | } |
1118 | | | 1118 | |
1119 | static void | | 1119 | static void |
1120 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *level) | | 1120 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *bl) |
1121 | { | | 1121 | { |
1122 | if (!tflag) | | 1122 | if (!tflag) |
1123 | return; | | 1123 | return; |
1124 | if (!(sclass == AUTO || sclass == REG)) | | 1124 | if (!(sclass == AUTO || sclass == REG)) |
1125 | return; | | 1125 | return; |
1126 | if (!(level->bl_enclosing == NULL)) | | 1126 | if (!(bl->bl_enclosing == NULL)) |
1127 | return; | | 1127 | return; |
1128 | if (is_scalar(level->bl_subtype->t_tspec)) | | 1128 | if (is_scalar(bl->bl_subtype->t_tspec)) |
1129 | return; | | 1129 | return; |
1130 | | | 1130 | |
1131 | /* no automatic aggregate initialization in trad. C */ | | 1131 | /* no automatic aggregate initialization in trad. C */ |
1132 | warning(188); | | 1132 | warning(188); |
1133 | } | | 1133 | } |
1134 | | | 1134 | |
1135 | static void | | 1135 | static void |
1136 | initialization_lbrace(struct initialization *in) | | 1136 | initialization_lbrace(struct initialization *in) |
1137 | { | | 1137 | { |
1138 | if (in->in_err) | | 1138 | if (in->in_err) |
1139 | return; | | 1139 | return; |
1140 | | | 1140 | |
1141 | debug_enter(); | | 1141 | debug_enter(); |
| @@ -1192,111 +1192,111 @@ initialization_rbrace(struct initializat | | | @@ -1192,111 +1192,111 @@ initialization_rbrace(struct initializat |
1192 | * | | 1192 | * |
1193 | * TODO: test the following initialization with an outer and an inner type: | | 1193 | * TODO: test the following initialization with an outer and an inner type: |
1194 | * | | 1194 | * |
1195 | * .deeply[0].nested = { | | 1195 | * .deeply[0].nested = { |
1196 | * .deeply[1].nested = { | | 1196 | * .deeply[1].nested = { |
1197 | * 12345, | | 1197 | * 12345, |
1198 | * }, | | 1198 | * }, |
1199 | * } | | 1199 | * } |
1200 | */ | | 1200 | */ |
1201 | static void | | 1201 | static void |
1202 | initialization_add_designator_subscript(struct initialization *in, | | 1202 | initialization_add_designator_subscript(struct initialization *in, |
1203 | range_t range) | | 1203 | range_t range) |
1204 | { | | 1204 | { |
1205 | struct brace_level *level; | | 1205 | struct brace_level *bl; |
1206 | | | 1206 | |
1207 | debug_enter(); | | 1207 | debug_enter(); |
1208 | if (range.lo == range.hi) | | 1208 | if (range.lo == range.hi) |
1209 | debug_step("subscript is %zu", range.hi); | | 1209 | debug_step("subscript is %zu", range.hi); |
1210 | else | | 1210 | else |
1211 | debug_step("subscript range is %zu ... %zu", | | 1211 | debug_step("subscript range is %zu ... %zu", |
1212 | range.lo, range.hi); | | 1212 | range.lo, range.hi); |
1213 | | | 1213 | |
1214 | /* XXX: This call is wrong here, it must be somewhere else. */ | | 1214 | /* XXX: This call is wrong here, it must be somewhere else. */ |
1215 | initialization_pop_nobrace(in); | | 1215 | initialization_pop_nobrace(in); |
1216 | | | 1216 | |
1217 | level = in->in_brace_level; | | 1217 | bl = in->in_brace_level; |
1218 | if (level->bl_array_of_unknown_size) { | | 1218 | if (bl->bl_array_of_unknown_size) { |
1219 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ | | 1219 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ |
1220 | int auto_dim = (int)range.hi; | | 1220 | int auto_dim = (int)range.hi; |
1221 | if (auto_dim > level->bl_type->t_dim) | | 1221 | if (auto_dim > bl->bl_type->t_dim) |
1222 | brace_level_set_array_dimension(level, auto_dim); | | 1222 | brace_level_set_array_dimension(bl, auto_dim); |
1223 | } | | 1223 | } |
1224 | | | 1224 | |
1225 | debug_leave(); | | 1225 | debug_leave(); |
1226 | } | | 1226 | } |
1227 | | | 1227 | |
1228 | /* Initialize a character array or wchar_t array with a string literal. */ | | 1228 | /* Initialize a character array or wchar_t array with a string literal. */ |
1229 | static bool | | 1229 | static bool |
1230 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) | | 1230 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) |
1231 | { | | 1231 | { |
1232 | struct brace_level *level; | | 1232 | struct brace_level *bl; |
1233 | strg_t *strg; | | 1233 | strg_t *strg; |
1234 | | | 1234 | |
1235 | if (tn->tn_op != STRING) | | 1235 | if (tn->tn_op != STRING) |
1236 | return false; | | 1236 | return false; |
1237 | | | 1237 | |
1238 | debug_enter(); | | 1238 | debug_enter(); |
1239 | | | 1239 | |
1240 | level = in->in_brace_level; | | 1240 | bl = in->in_brace_level; |
1241 | strg = tn->tn_string; | | 1241 | strg = tn->tn_string; |
1242 | | | 1242 | |
1243 | /* | | 1243 | /* |
1244 | * Check if we have an array type which can be initialized by | | 1244 | * Check if we have an array type which can be initialized by |
1245 | * the string. | | 1245 | * the string. |
1246 | */ | | 1246 | */ |
1247 | if (is_string_array(level->bl_subtype, strg->st_tspec)) { | | 1247 | if (is_string_array(bl->bl_subtype, strg->st_tspec)) { |
1248 | debug_step("subtype is an array"); | | 1248 | debug_step("subtype is an array"); |
1249 | | | 1249 | |
1250 | /* Put the array at top of stack */ | | 1250 | /* Put the array at top of stack */ |
1251 | initialization_push(in); | | 1251 | initialization_push(in); |
1252 | level = in->in_brace_level; | | 1252 | bl = in->in_brace_level; |
1253 | | | 1253 | |
1254 | } else if (is_string_array(level->bl_type, strg->st_tspec)) { | | 1254 | } else if (is_string_array(bl->bl_type, strg->st_tspec)) { |
1255 | debug_step("type is an array"); | | 1255 | debug_step("type is an array"); |
1256 | | | 1256 | |
1257 | /* | | 1257 | /* |
1258 | * If the array is already partly initialized, we are | | 1258 | * If the array is already partly initialized, we are |
1259 | * wrong here. | | 1259 | * wrong here. |
1260 | */ | | 1260 | */ |
1261 | if (level->bl_remaining != level->bl_type->t_dim) | | 1261 | if (bl->bl_remaining != bl->bl_type->t_dim) |
1262 | goto nope; | | 1262 | goto nope; |
1263 | } else | | 1263 | } else |
1264 | goto nope; | | 1264 | goto nope; |
1265 | | | 1265 | |
1266 | if (level->bl_array_of_unknown_size) { | | 1266 | if (bl->bl_array_of_unknown_size) { |
1267 | level->bl_array_of_unknown_size = false; | | 1267 | bl->bl_array_of_unknown_size = false; |
1268 | level->bl_type->t_dim = (int)(strg->st_len + 1); | | 1268 | bl->bl_type->t_dim = (int)(strg->st_len + 1); |
1269 | setcomplete(level->bl_type, true); | | 1269 | setcomplete(bl->bl_type, true); |
1270 | } else { | | 1270 | } else { |
1271 | /* | | 1271 | /* |
1272 | * TODO: check for buffer overflow in the object to be | | 1272 | * TODO: check for buffer overflow in the object to be |
1273 | * initialized | | 1273 | * initialized |
1274 | */ | | 1274 | */ |
1275 | /* XXX: double-check for off-by-one error */ | | 1275 | /* XXX: double-check for off-by-one error */ |
1276 | if (level->bl_type->t_dim < (int)strg->st_len) { | | 1276 | if (bl->bl_type->t_dim < (int)strg->st_len) { |
1277 | /* non-null byte ignored in string initializer */ | | 1277 | /* non-null byte ignored in string initializer */ |
1278 | warning(187); | | 1278 | warning(187); |
1279 | } | | 1279 | } |
1280 | | | 1280 | |
1281 | /* | | 1281 | /* |
1282 | * TODO: C99 6.7.8p14 allows a string literal to be enclosed | | 1282 | * TODO: C99 6.7.8p14 allows a string literal to be enclosed |
1283 | * in optional redundant braces, just like scalars. Add tests | | 1283 | * in optional redundant braces, just like scalars. Add tests |
1284 | * for this. | | 1284 | * for this. |
1285 | */ | | 1285 | */ |
1286 | } | | 1286 | } |
1287 | | | 1287 | |
1288 | /* In every case the array is initialized completely. */ | | 1288 | /* In every case the array is initialized completely. */ |
1289 | level->bl_remaining = 0; | | 1289 | bl->bl_remaining = 0; |
1290 | | | 1290 | |
1291 | initialization_debug(in); | | 1291 | initialization_debug(in); |
1292 | debug_leave(); | | 1292 | debug_leave(); |
1293 | return true; | | 1293 | return true; |
1294 | nope: | | 1294 | nope: |
1295 | debug_leave(); | | 1295 | debug_leave(); |
1296 | return false; | | 1296 | return false; |
1297 | } | | 1297 | } |
1298 | | | 1298 | |
1299 | /* | | 1299 | /* |
1300 | * Initialize a non-array object with automatic storage duration and only a | | 1300 | * Initialize a non-array object with automatic storage duration and only a |
1301 | * single initializer expression without braces by delegating to ASSIGN. | | 1301 | * single initializer expression without braces by delegating to ASSIGN. |
1302 | */ | | 1302 | */ |
| @@ -1331,39 +1331,39 @@ initialization_next_nobrace(struct initi | | | @@ -1331,39 +1331,39 @@ initialization_next_nobrace(struct initi |
1331 | | | 1331 | |
1332 | if (in->in_brace_level->bl_type == NULL && | | 1332 | if (in->in_brace_level->bl_type == NULL && |
1333 | !is_scalar(in->in_brace_level->bl_subtype->t_tspec)) { | | 1333 | !is_scalar(in->in_brace_level->bl_subtype->t_tspec)) { |
1334 | /* {}-enclosed initializer required */ | | 1334 | /* {}-enclosed initializer required */ |
1335 | error(181); | | 1335 | error(181); |
1336 | /* XXX: maybe set initerr here */ | | 1336 | /* XXX: maybe set initerr here */ |
1337 | } | | 1337 | } |
1338 | | | 1338 | |
1339 | if (!in->in_err && | | 1339 | if (!in->in_err && |
1340 | !brace_level_check_too_many_initializers(in->in_brace_level)) | | 1340 | !brace_level_check_too_many_initializers(in->in_brace_level)) |
1341 | initialization_set_error(in); | | 1341 | initialization_set_error(in); |
1342 | | | 1342 | |
1343 | while (!in->in_err) { | | 1343 | while (!in->in_err) { |
1344 | struct brace_level *level = in->in_brace_level; | | 1344 | struct brace_level *bl = in->in_brace_level; |
1345 | | | 1345 | |
1346 | if (tn->tn_type->t_tspec == STRUCT && | | 1346 | if (tn->tn_type->t_tspec == STRUCT && |
1347 | level->bl_type == tn->tn_type && | | 1347 | bl->bl_type == tn->tn_type && |
1348 | level->bl_enclosing != NULL && | | 1348 | bl->bl_enclosing != NULL && |
1349 | level->bl_enclosing->bl_enclosing != NULL) { | | 1349 | bl->bl_enclosing->bl_enclosing != NULL) { |
1350 | level->bl_brace = false; | | 1350 | bl->bl_brace = false; |
1351 | level->bl_remaining = 1; /* the struct itself */ | | 1351 | bl->bl_remaining = 1; /* the struct itself */ |
1352 | break; | | 1352 | break; |
1353 | } | | 1353 | } |
1354 | | | 1354 | |
1355 | if (level->bl_type != NULL && | | 1355 | if (bl->bl_type != NULL && |
1356 | is_scalar(level->bl_type->t_tspec)) | | 1356 | is_scalar(bl->bl_type->t_tspec)) |
1357 | break; | | 1357 | break; |
1358 | initialization_push(in); | | 1358 | initialization_push(in); |
1359 | } | | 1359 | } |
1360 | | | 1360 | |
1361 | initialization_debug(in); | | 1361 | initialization_debug(in); |
1362 | debug_leave(); | | 1362 | debug_leave(); |
1363 | } | | 1363 | } |
1364 | | | 1364 | |
1365 | static void | | 1365 | static void |
1366 | initialization_expr(struct initialization *in, tnode_t *tn) | | 1366 | initialization_expr(struct initialization *in, tnode_t *tn) |
1367 | { | | 1367 | { |
1368 | | | 1368 | |
1369 | debug_enter(); | | 1369 | debug_enter(); |