| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.171 2021/03/28 18:33:27 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.172 2021/03/28 19:30:08 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.171 2021/03/28 18:33:27 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.172 2021/03/28 19:30:08 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 | * |
| @@ -579,54 +579,54 @@ brace_level_look_up_member(const struct | | | @@ -579,54 +579,54 @@ brace_level_look_up_member(const struct |
579 | | | 579 | |
580 | for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { | | 580 | for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { |
581 | if (m->s_bitfield && m->s_name == unnamed) | | 581 | if (m->s_bitfield && m->s_name == unnamed) |
582 | continue; | | 582 | continue; |
583 | if (strcmp(m->s_name, name) == 0) | | 583 | if (strcmp(m->s_name, name) == 0) |
584 | return m; | | 584 | return m; |
585 | } | | 585 | } |
586 | | | 586 | |
587 | return NULL; | | 587 | return NULL; |
588 | } | | 588 | } |
589 | | | 589 | |
590 | /* TODO: merge duplicate code */ | | 590 | /* TODO: merge duplicate code */ |
591 | static sym_t * | | 591 | static sym_t * |
592 | brace_level_look_up_member_bloated(struct brace_level *level, | | 592 | brace_level_look_up_member_named(struct brace_level *level, const char *name, |
593 | const struct designator *dr, int *count) | | 593 | int *count) |
594 | { | | 594 | { |
595 | sym_t *m; | | 595 | sym_t *m; |
596 | | | 596 | |
597 | for (m = level->bl_type->t_str->sou_first_member; | | 597 | for (m = level->bl_type->t_str->sou_first_member; |
598 | m != NULL; m = m->s_next) { | | 598 | m != NULL; m = m->s_next) { |
599 | if (m->s_bitfield && m->s_name == unnamed) | | 599 | if (m->s_bitfield && m->s_name == unnamed) |
600 | continue; | | 600 | continue; |
601 | /* | | 601 | if (strcmp(m->s_name, name) != 0) |
602 | * TODO: split into separate functions: | | 602 | continue; |
603 | * | | 603 | (*count)++; |
604 | * look_up_array_next | | 604 | break; |
605 | * look_up_array_designator | | 605 | } |
606 | * look_up_struct_next | | | |
607 | * look_up_struct_designator | | | |
608 | */ | | | |
609 | if (dr != NULL) { | | | |
610 | /* XXX: this log entry looks unnecessarily verbose */ | | | |
611 | debug_step("have member '%s', want member '%s'", | | | |
612 | m->s_name, dr->name); | | | |
613 | if (strcmp(m->s_name, dr->name) == 0) { | | | |
614 | (*count)++; | | | |
615 | break; | | | |
616 | } else | | | |
617 | continue; | | | |
618 | } | | | |
619 | | | 606 | |
| | | 607 | return m; |
| | | 608 | } |
| | | 609 | |
| | | 610 | /* TODO: merge duplicate code */ |
| | | 611 | static sym_t * |
| | | 612 | brace_level_look_up_member_unnamed(struct brace_level *level, int *count) |
| | | 613 | { |
| | | 614 | sym_t *m; |
| | | 615 | |
| | | 616 | for (m = level->bl_type->t_str->sou_first_member; |
| | | 617 | m != NULL; m = m->s_next) { |
| | | 618 | if (m->s_bitfield && m->s_name == unnamed) |
| | | 619 | continue; |
620 | /* XXX: What is this code for? */ | | 620 | /* XXX: What is this code for? */ |
621 | if (++(*count) == 1) { | | 621 | if (++(*count) == 1) { |
622 | level->bl_next_member = m; | | 622 | level->bl_next_member = m; |
623 | level->bl_subtype = m->s_type; | | 623 | level->bl_subtype = m->s_type; |
624 | } | | 624 | } |
625 | } | | 625 | } |
626 | | | 626 | |
627 | return m; | | 627 | return m; |
628 | } | | 628 | } |
629 | | | 629 | |
630 | /* TODO: document me */ | | 630 | /* TODO: document me */ |
631 | /* TODO: think of a better name than 'push' */ | | 631 | /* TODO: think of a better name than 'push' */ |
632 | static bool | | 632 | static bool |
| @@ -802,49 +802,48 @@ initialization_init(struct initializatio | | | @@ -802,49 +802,48 @@ initialization_init(struct initializatio |
802 | } | | 802 | } |
803 | | | 803 | |
804 | static void | | 804 | static void |
805 | initialization_set_error(struct initialization *in) | | 805 | initialization_set_error(struct initialization *in) |
806 | { | | 806 | { |
807 | in->initerr = true; | | 807 | in->initerr = true; |
808 | } | | 808 | } |
809 | | | 809 | |
810 | /* TODO: document me */ | | 810 | /* TODO: document me */ |
811 | /* TODO: think of a better name than 'push' */ | | 811 | /* TODO: think of a better name than 'push' */ |
812 | static bool | | 812 | static bool |
813 | initialization_push_struct_or_union(struct initialization *in) | | 813 | initialization_push_struct_or_union(struct initialization *in) |
814 | { | | 814 | { |
815 | /* | | | |
816 | * TODO: remove unnecessary 'const' for variables in functions that | | | |
817 | * fit on a single screen. Keep it for larger functions. | | | |
818 | */ | | | |
819 | struct brace_level *level = in->brace_level; | | 815 | struct brace_level *level = in->brace_level; |
820 | int cnt; | | 816 | int cnt; |
821 | sym_t *m; | | 817 | sym_t *m; |
822 | | | 818 | |
823 | if (is_incomplete(level->bl_type)) { | | 819 | if (is_incomplete(level->bl_type)) { |
824 | /* initialization of an incomplete type */ | | 820 | /* initialization of an incomplete type */ |
825 | error(175); | | 821 | error(175); |
826 | initialization_set_error(in); | | 822 | initialization_set_error(in); |
827 | return false; | | 823 | return false; |
828 | } | | 824 | } |
829 | | | 825 | |
830 | cnt = 0; | | 826 | cnt = 0; |
831 | designation_debug(&in->designation); | | 827 | designation_debug(&in->designation); |
832 | debug_step("lookup for '%s'%s", | | 828 | debug_step("lookup for '%s'%s", |
833 | type_name(level->bl_type), | | 829 | type_name(level->bl_type), |
834 | level->bl_seen_named_member ? ", seen named member" : ""); | | 830 | level->bl_seen_named_member ? ", seen named member" : ""); |
835 | | | 831 | |
836 | m = brace_level_look_up_member_bloated(level, | | 832 | if (in->designation.head != NULL) |
837 | in->designation.head, &cnt); | | 833 | m = brace_level_look_up_member_named(level, |
| | | 834 | in->designation.head->name, &cnt); |
| | | 835 | else |
| | | 836 | m = brace_level_look_up_member_unnamed(level, &cnt); |
838 | | | 837 | |
839 | if (in->designation.head != NULL) { | | 838 | if (in->designation.head != NULL) { |
840 | if (m == NULL) { | | 839 | if (m == NULL) { |
841 | debug_step("pop struct"); | | 840 | debug_step("pop struct"); |
842 | return true; | | 841 | return true; |
843 | } | | 842 | } |
844 | level->bl_next_member = m; | | 843 | level->bl_next_member = m; |
845 | level->bl_subtype = m->s_type; | | 844 | level->bl_subtype = m->s_type; |
846 | level->bl_seen_named_member = true; | | 845 | level->bl_seen_named_member = true; |
847 | debug_step("named member '%s'", | | 846 | debug_step("named member '%s'", |
848 | in->designation.head->name); | | 847 | in->designation.head->name); |
849 | designation_shift_level(&in->designation); | | 848 | designation_shift_level(&in->designation); |
850 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; | | 849 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; |