| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.191 2021/04/02 14:19:33 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.192 2021/04/02 14:32:27 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | | 4 | * Copyright (c) 1994, 1995 Jochen Pohl |
5 | * Copyright (c) 2021 Roland Illig | | 5 | * Copyright (c) 2021 Roland Illig |
6 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -28,27 +28,27 @@ | | | @@ -28,27 +28,27 @@ |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
36 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(__RCSID) && !defined(lint) | | 40 | #if defined(__RCSID) && !defined(lint) |
41 | __RCSID("$NetBSD: init.c,v 1.191 2021/04/02 14:19:33 rillig Exp $"); | | 41 | __RCSID("$NetBSD: init.c,v 1.192 2021/04/02 14:32:27 rillig Exp $"); |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <stdlib.h> | | 44 | #include <stdlib.h> |
45 | #include <string.h> | | 45 | #include <string.h> |
46 | | | 46 | |
47 | #include "lint1.h" | | 47 | #include "lint1.h" |
48 | | | 48 | |
49 | | | 49 | |
50 | /* | | 50 | /* |
51 | * Initialization of global or local objects, like in: | | 51 | * Initialization of global or local objects, like in: |
52 | * | | 52 | * |
53 | * int number = 12345; | | 53 | * int number = 12345; |
54 | * int number_with_braces = { 12345 }; | | 54 | * int number_with_braces = { 12345 }; |
| @@ -112,31 +112,33 @@ struct designation { | | | @@ -112,31 +112,33 @@ struct designation { |
112 | }; | | 112 | }; |
113 | | | 113 | |
114 | /* | | 114 | /* |
115 | * Describes a single brace level of an ongoing initialization. | | 115 | * Describes a single brace level of an ongoing initialization. |
116 | * | | 116 | * |
117 | * See C99 6.7.8p17. | | 117 | * See C99 6.7.8p17. |
118 | */ | | 118 | */ |
119 | struct brace_level { | | 119 | struct brace_level { |
120 | /* | | 120 | /* |
121 | * The type of the current object that is initialized at this brace | | 121 | * The type of the current object that is initialized at this brace |
122 | * level. | | 122 | * level. |
123 | */ | | 123 | */ |
124 | const type_t *bl_type; | | 124 | const type_t *bl_type; |
125 | const sym_t *bl_next_member; /* for structs and unions */ | | 125 | |
126 | size_t bl_array_next_subscript; | | 126 | const sym_t *bl_member; /* for structs and unions */ |
| | | 127 | size_t bl_subscript; /* for arrays */ |
127 | bool bl_scalar_done: 1; /* for scalars */ | | 128 | bool bl_scalar_done: 1; /* for scalars */ |
128 | bool bl_confused: 1; /* skip further checks */ | | 129 | bool bl_confused: 1; /* skip further checks */ |
129 | struct designation bl_designation; /* .member[123].member */ | | 130 | struct designation bl_designation; /* .member[123].member */ |
| | | 131 | |
130 | struct brace_level *bl_enclosing; | | 132 | struct brace_level *bl_enclosing; |
131 | }; | | 133 | }; |
132 | | | 134 | |
133 | struct initialization { | | 135 | struct initialization { |
134 | /* | | 136 | /* |
135 | * Is set as soon as a fatal error occurred in the initialization. | | 137 | * Is set as soon as a fatal error occurred in the initialization. |
136 | * The effect is that the rest of the initialization is ignored | | 138 | * The effect is that the rest of the initialization is ignored |
137 | * (parsed by yacc, expression trees built, but no initialization | | 139 | * (parsed by yacc, expression trees built, but no initialization |
138 | * takes place). | | 140 | * takes place). |
139 | */ | | 141 | */ |
140 | bool in_err; | | 142 | bool in_err; |
141 | | | 143 | |
142 | /* The symbol that is to be initialized. */ | | 144 | /* The symbol that is to be initialized. */ |
| @@ -539,84 +541,80 @@ designation_reset(struct designation *dn | | | @@ -539,84 +541,80 @@ designation_reset(struct designation *dn |
539 | dn->dn_tail = NULL; | | 541 | dn->dn_tail = NULL; |
540 | } | | 542 | } |
541 | | | 543 | |
542 | | | 544 | |
543 | static struct brace_level * | | 545 | static struct brace_level * |
544 | brace_level_new(const type_t *tp, struct brace_level *enclosing) | | 546 | brace_level_new(const type_t *tp, struct brace_level *enclosing) |
545 | { | | 547 | { |
546 | struct brace_level *bl; | | 548 | struct brace_level *bl; |
547 | | | 549 | |
548 | bl = xcalloc(1, sizeof(*bl)); | | 550 | bl = xcalloc(1, sizeof(*bl)); |
549 | bl->bl_type = tp; | | 551 | bl->bl_type = tp; |
550 | bl->bl_enclosing = enclosing; | | 552 | bl->bl_enclosing = enclosing; |
551 | if (is_struct_or_union(tp->t_tspec)) | | 553 | if (is_struct_or_union(tp->t_tspec)) |
552 | bl->bl_next_member = first_named_member(tp); | | 554 | bl->bl_member = first_named_member(tp); |
553 | | | 555 | |
554 | return bl; | | 556 | return bl; |
555 | } | | 557 | } |
556 | | | 558 | |
557 | static void | | 559 | static void |
558 | brace_level_free(struct brace_level *bl) | | 560 | brace_level_free(struct brace_level *bl) |
559 | { | | 561 | { |
560 | | | 562 | |
561 | designation_reset(&bl->bl_designation); | | 563 | designation_reset(&bl->bl_designation); |
562 | free(bl); | | 564 | free(bl); |
563 | } | | 565 | } |
564 | | | 566 | |
565 | #ifdef DEBUG | | 567 | #ifdef DEBUG |
566 | static void | | 568 | static void |
567 | brace_level_debug(const struct brace_level *bl) | | 569 | brace_level_debug(const struct brace_level *bl) |
568 | { | | 570 | { |
569 | | | 571 | |
570 | lint_assert(bl->bl_type != NULL); | | 572 | lint_assert(bl->bl_type != NULL); |
571 | lint_assert(bl->bl_next_member == NULL || | | 573 | lint_assert(bl->bl_member == NULL || !is_unnamed(bl->bl_member)); |
572 | !is_unnamed(bl->bl_next_member)); | | | |
573 | | | 574 | |
574 | debug_printf("type '%s'", type_name(bl->bl_type)); | | 575 | debug_printf("type '%s'", type_name(bl->bl_type)); |
575 | | | 576 | |
576 | if (is_struct_or_union(bl->bl_type->t_tspec) && | | 577 | if (is_struct_or_union(bl->bl_type->t_tspec) && bl->bl_member != NULL) |
577 | bl->bl_next_member != NULL) | | 578 | debug_printf(", member '%s'", bl->bl_member->s_name); |
578 | debug_printf(", next member '%s'", | | | |
579 | bl->bl_next_member->s_name); | | | |
580 | if (bl->bl_type->t_tspec == ARRAY) | | 579 | if (bl->bl_type->t_tspec == ARRAY) |
581 | debug_printf(", next array subscript %zu", | | 580 | debug_printf(", subscript %zu", bl->bl_subscript); |
582 | bl->bl_array_next_subscript); | | | |
583 | | | 581 | |
584 | debug_printf("\n"); | | 582 | debug_printf("\n"); |
585 | } | | 583 | } |
586 | #else | | 584 | #else |
587 | #define brace_level_debug(level) do { } while (false) | | 585 | #define brace_level_debug(level) do { } while (false) |
588 | #endif | | 586 | #endif |
589 | | | 587 | |
590 | static const type_t * | | 588 | static const type_t * |
591 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) | | 589 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) |
592 | { | | 590 | { |
593 | | | 591 | |
594 | if (bl->bl_next_member == NULL) { | | 592 | if (bl->bl_member == NULL) { |
595 | /* too many struct/union initializers */ | | 593 | /* too many struct/union initializers */ |
596 | error(172); | | 594 | error(172); |
597 | return NULL; | | 595 | return NULL; |
598 | } | | 596 | } |
599 | | | 597 | |
600 | lint_assert(!is_unnamed(bl->bl_next_member)); | | 598 | lint_assert(!is_unnamed(bl->bl_member)); |
601 | return sym_type(bl->bl_next_member); | | 599 | return sym_type(bl->bl_member); |
602 | } | | 600 | } |
603 | | | 601 | |
604 | static const type_t * | | 602 | static const type_t * |
605 | brace_level_sub_type_array(const struct brace_level *bl) | | 603 | brace_level_sub_type_array(const struct brace_level *bl) |
606 | { | | 604 | { |
607 | | | 605 | |
608 | if (!bl->bl_confused && !bl->bl_type->t_incomplete_array && | | 606 | if (!bl->bl_confused && !bl->bl_type->t_incomplete_array && |
609 | bl->bl_array_next_subscript >= (size_t)bl->bl_type->t_dim) { | | 607 | bl->bl_subscript >= (size_t)bl->bl_type->t_dim) { |
610 | /* too many array initializers, expected %d */ | | 608 | /* too many array initializers, expected %d */ |
611 | error(173, bl->bl_type->t_dim); | | 609 | error(173, bl->bl_type->t_dim); |
612 | } | | 610 | } |
613 | | | 611 | |
614 | return bl->bl_type->t_subt; | | 612 | return bl->bl_type->t_subt; |
615 | } | | 613 | } |
616 | | | 614 | |
617 | static const type_t * | | 615 | static const type_t * |
618 | brace_level_sub_type_scalar(const struct brace_level *bl) | | 616 | brace_level_sub_type_scalar(const struct brace_level *bl) |
619 | { | | 617 | { |
620 | | | 618 | |
621 | if (bl->bl_scalar_done) { | | 619 | if (bl->bl_scalar_done) { |
622 | /* too many initializers */ | | 620 | /* too many initializers */ |
| @@ -635,72 +633,73 @@ brace_level_sub_type(const struct brace_ | | | @@ -635,72 +633,73 @@ brace_level_sub_type(const struct brace_ |
635 | return designation_look_up(&bl->bl_designation, bl->bl_type); | | 633 | return designation_look_up(&bl->bl_designation, bl->bl_type); |
636 | | | 634 | |
637 | switch (bl->bl_type->t_tspec) { | | 635 | switch (bl->bl_type->t_tspec) { |
638 | case STRUCT: | | 636 | case STRUCT: |
639 | case UNION: | | 637 | case UNION: |
640 | return brace_level_sub_type_struct_or_union(bl); | | 638 | return brace_level_sub_type_struct_or_union(bl); |
641 | case ARRAY: | | 639 | case ARRAY: |
642 | return brace_level_sub_type_array(bl); | | 640 | return brace_level_sub_type_array(bl); |
643 | default: | | 641 | default: |
644 | return brace_level_sub_type_scalar(bl); | | 642 | return brace_level_sub_type_scalar(bl); |
645 | } | | 643 | } |
646 | } | | 644 | } |
647 | | | 645 | |
| | | 646 | /* C99 6.7.8p17 */ |
648 | static void | | 647 | static void |
649 | brace_level_apply_designation(struct brace_level *bl) | | 648 | brace_level_apply_designation(struct brace_level *bl) |
650 | { | | 649 | { |
651 | const struct designator *dr = bl->bl_designation.dn_head; | | 650 | const struct designator *dr = bl->bl_designation.dn_head; |
652 | | | 651 | |
653 | if (dr == NULL) | | 652 | if (dr == NULL) |
654 | return; | | 653 | return; |
655 | | | 654 | |
656 | designation_debug(&bl->bl_designation); | | 655 | designation_debug(&bl->bl_designation); |
657 | | | 656 | |
658 | switch (bl->bl_type->t_tspec) { | | 657 | switch (bl->bl_type->t_tspec) { |
659 | case STRUCT: | | 658 | case STRUCT: |
660 | case UNION: | | 659 | case UNION: |
661 | if (dr->dr_name == NULL) | | 660 | if (dr->dr_name == NULL) |
662 | return; /* error, silently ignored */ | | 661 | return; /* error, silently ignored */ |
663 | bl->bl_next_member = look_up_member(bl->bl_type, dr->dr_name); | | 662 | bl->bl_member = look_up_member(bl->bl_type, dr->dr_name); |
664 | break; | | 663 | break; |
665 | case ARRAY: | | 664 | case ARRAY: |
666 | if (dr->dr_name != NULL) | | 665 | if (dr->dr_name != NULL) |
667 | return; /* error, silently ignored */ | | 666 | return; /* error, silently ignored */ |
668 | bl->bl_array_next_subscript = dr->dr_subscript; | | 667 | bl->bl_subscript = dr->dr_subscript; |
669 | break; | | 668 | break; |
670 | default: | | 669 | default: |
671 | break; /* error, silently ignored */ | | 670 | break; /* error, silently ignored */ |
672 | } | | 671 | } |
673 | } | | 672 | } |
674 | | | 673 | |
675 | /* | | 674 | /* |
676 | * After initializing a sub-object, advance to the next sub-object. | | 675 | * After initializing a sub-object, advance to the next sub-object. |
677 | * | | 676 | * |
678 | * C99 6.7.8p17 | | 677 | * C99 6.7.8p17 |
679 | */ | | 678 | */ |
680 | static void | | 679 | static void |
681 | brace_level_advance(struct brace_level *bl) | | 680 | brace_level_advance(struct brace_level *bl) |
682 | { | | 681 | { |
683 | | | 682 | |
684 | switch (bl->bl_type->t_tspec) { | | 683 | switch (bl->bl_type->t_tspec) { |
685 | case STRUCT: | | 684 | case STRUCT: |
686 | lint_assert(bl->bl_next_member != NULL); | | 685 | lint_assert(bl->bl_member != NULL); |
687 | bl->bl_next_member = skip_unnamed(bl->bl_next_member->s_next); | | 686 | bl->bl_member = skip_unnamed(bl->bl_member->s_next); |
688 | break; | | 687 | break; |
689 | case UNION: | | 688 | case UNION: |
690 | bl->bl_next_member = NULL; | | 689 | bl->bl_member = NULL; |
691 | break; | | 690 | break; |
692 | case ARRAY: | | 691 | case ARRAY: |
693 | bl->bl_array_next_subscript++; | | 692 | bl->bl_subscript++; |
694 | break; | | 693 | break; |
695 | default: | | 694 | default: |
696 | bl->bl_scalar_done = true; | | 695 | bl->bl_scalar_done = true; |
697 | break; | | 696 | break; |
698 | } | | 697 | } |
699 | } | | 698 | } |
700 | | | 699 | |
701 | | | 700 | |
702 | static struct initialization * | | 701 | static struct initialization * |
703 | initialization_new(sym_t *sym) | | 702 | initialization_new(sym_t *sym) |
704 | { | | 703 | { |
705 | struct initialization *in; | | 704 | struct initialization *in; |
706 | | | 705 | |
| @@ -803,27 +802,27 @@ initialization_begin_brace_level(struct | | | @@ -803,27 +802,27 @@ initialization_begin_brace_level(struct |
803 | done: | | 802 | done: |
804 | initialization_debug(in); | | 803 | initialization_debug(in); |
805 | debug_leave(); | | 804 | debug_leave(); |
806 | } | | 805 | } |
807 | | | 806 | |
808 | /* C99 6.7.8p22 */ | | 807 | /* C99 6.7.8p22 */ |
809 | static void | | 808 | static void |
810 | initialization_set_size_of_unknown_array(struct initialization *in) | | 809 | initialization_set_size_of_unknown_array(struct initialization *in) |
811 | { | | 810 | { |
812 | | | 811 | |
813 | if (in->in_sym->s_type->t_incomplete_array && | | 812 | if (in->in_sym->s_type->t_incomplete_array && |
814 | in->in_brace_level->bl_enclosing == NULL) | | 813 | in->in_brace_level->bl_enclosing == NULL) |
815 | update_type_of_array_of_unknown_size(in->in_sym, | | 814 | update_type_of_array_of_unknown_size(in->in_sym, |
816 | in->in_brace_level->bl_array_next_subscript); | | 815 | in->in_brace_level->bl_subscript); |
817 | } | | 816 | } |
818 | | | 817 | |
819 | static void | | 818 | static void |
820 | initialization_end_brace_level(struct initialization *in) | | 819 | initialization_end_brace_level(struct initialization *in) |
821 | { | | 820 | { |
822 | struct brace_level *bl; | | 821 | struct brace_level *bl; |
823 | | | 822 | |
824 | if (in->in_err) | | 823 | if (in->in_err) |
825 | return; | | 824 | return; |
826 | | | 825 | |
827 | debug_enter(); | | 826 | debug_enter(); |
828 | | | 827 | |
829 | initialization_set_size_of_unknown_array(in); | | 828 | initialization_set_size_of_unknown_array(in); |
| @@ -890,38 +889,37 @@ initialization_init_array_using_string(s | | | @@ -890,38 +889,37 @@ initialization_init_array_using_string(s |
890 | struct brace_level *bl; | | 889 | struct brace_level *bl; |
891 | const type_t *tp; | | 890 | const type_t *tp; |
892 | strg_t *strg; | | 891 | strg_t *strg; |
893 | | | 892 | |
894 | if (tn->tn_op != STRING) | | 893 | if (tn->tn_op != STRING) |
895 | return false; | | 894 | return false; |
896 | | | 895 | |
897 | bl = in->in_brace_level; | | 896 | bl = in->in_brace_level; |
898 | tp = initialization_sub_type(in); | | 897 | tp = initialization_sub_type(in); |
899 | strg = tn->tn_string; | | 898 | strg = tn->tn_string; |
900 | | | 899 | |
901 | if (!is_string_array(tp, strg->st_tspec)) | | 900 | if (!is_string_array(tp, strg->st_tspec)) |
902 | return false; | | 901 | return false; |
903 | if (bl != NULL && tp->t_tspec != ARRAY && | | 902 | if (bl != NULL && tp->t_tspec != ARRAY && bl->bl_subscript != 0) |
904 | bl->bl_array_next_subscript != 0) | | | |
905 | return false; | | 903 | return false; |
906 | | | 904 | |
907 | if (bl != NULL && tp->t_dim < (int)strg->st_len) { | | 905 | if (bl != NULL && tp->t_dim < (int)strg->st_len) { |
908 | /* non-null byte ignored in string initializer */ | | 906 | /* non-null byte ignored in string initializer */ |
909 | warning(187); | | 907 | warning(187); |
910 | } | | 908 | } |
911 | | | 909 | |
912 | if (tp == in->in_sym->s_type && tp->t_incomplete_array) { | | 910 | if (tp == in->in_sym->s_type && tp->t_incomplete_array) { |
913 | if (bl != NULL) { | | 911 | if (bl != NULL) { |
914 | bl->bl_array_next_subscript = strg->st_len + 1; | | 912 | bl->bl_subscript = strg->st_len + 1; |
915 | /* see initialization_set_size_of_unknown_array */ | | 913 | /* see initialization_set_size_of_unknown_array */ |
916 | } else | | 914 | } else |
917 | update_type_of_array_of_unknown_size(in->in_sym, | | 915 | update_type_of_array_of_unknown_size(in->in_sym, |
918 | strg->st_len + 1); | | 916 | strg->st_len + 1); |
919 | } | | 917 | } |
920 | | | 918 | |
921 | return true; | | 919 | return true; |
922 | } | | 920 | } |
923 | | | 921 | |
924 | /* | | 922 | /* |
925 | * Initialize a single sub-object as part of the currently ongoing | | 923 | * Initialize a single sub-object as part of the currently ongoing |
926 | * initialization. | | 924 | * initialization. |
927 | */ | | 925 | */ |