| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.183 2021/03/30 16:07:07 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.184 2021/03/30 20:23:30 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.183 2021/03/30 16:07:07 rillig Exp $"); | | 41 | __RCSID("$NetBSD: init.c,v 1.184 2021/03/30 20:23:30 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 }; |
| @@ -524,26 +524,29 @@ designation_look_up(const struct designa | | | @@ -524,26 +524,29 @@ designation_look_up(const struct designa |
524 | } | | 524 | } |
525 | | | 525 | |
526 | | | 526 | |
527 | | | 527 | |
528 | static void | | 528 | static void |
529 | designation_reset(struct designation *dn) | | 529 | designation_reset(struct designation *dn) |
530 | { | | 530 | { |
531 | struct designator *dr, *next; | | 531 | struct designator *dr, *next; |
532 | | | 532 | |
533 | for (dr = dn->dn_head; dr != NULL; dr = next) { | | 533 | for (dr = dn->dn_head; dr != NULL; dr = next) { |
534 | next = dr->dr_next; | | 534 | next = dr->dr_next; |
535 | designator_free(dr); | | 535 | designator_free(dr); |
536 | } | | 536 | } |
| | | 537 | |
| | | 538 | dn->dn_head = NULL; |
| | | 539 | dn->dn_tail = NULL; |
537 | } | | 540 | } |
538 | | | 541 | |
539 | | | 542 | |
540 | static struct brace_level * | | 543 | static struct brace_level * |
541 | brace_level_new(const type_t *tp, struct brace_level *enclosing) | | 544 | brace_level_new(const type_t *tp, struct brace_level *enclosing) |
542 | { | | 545 | { |
543 | struct brace_level *bl; | | 546 | struct brace_level *bl; |
544 | | | 547 | |
545 | bl = xcalloc(1, sizeof(*bl)); | | 548 | bl = xcalloc(1, sizeof(*bl)); |
546 | bl->bl_type = tp; | | 549 | bl->bl_type = tp; |
547 | bl->bl_enclosing = enclosing; | | 550 | bl->bl_enclosing = enclosing; |
548 | if (is_struct_or_union(tp->t_tspec)) | | 551 | if (is_struct_or_union(tp->t_tspec)) |
549 | bl->bl_next_member = first_named_member(tp); | | 552 | bl->bl_next_member = first_named_member(tp); |
| @@ -577,41 +580,26 @@ brace_level_debug(const struct brace_lev | | | @@ -577,41 +580,26 @@ brace_level_debug(const struct brace_lev |
577 | bl->bl_next_member != NULL) | | 580 | bl->bl_next_member != NULL) |
578 | debug_printf(", next member '%s'", | | 581 | debug_printf(", next member '%s'", |
579 | bl->bl_next_member->s_name); | | 582 | bl->bl_next_member->s_name); |
580 | if (bl->bl_type->t_tspec == ARRAY) | | 583 | if (bl->bl_type->t_tspec == ARRAY) |
581 | debug_printf(", next array subscript %zu", | | 584 | debug_printf(", next array subscript %zu", |
582 | bl->bl_array_next_subscript); | | 585 | bl->bl_array_next_subscript); |
583 | | | 586 | |
584 | debug_printf("\n"); | | 587 | debug_printf("\n"); |
585 | } | | 588 | } |
586 | #else | | 589 | #else |
587 | #define brace_level_debug(level) do { } while (false) | | 590 | #define brace_level_debug(level) do { } while (false) |
588 | #endif | | 591 | #endif |
589 | | | 592 | |
590 | static void | | | |
591 | brace_level_remove_designation(struct brace_level *bl) | | | |
592 | { | | | |
593 | struct designator *dr, *next; | | | |
594 | | | | |
595 | for (dr = bl->bl_designation.dn_head; dr != NULL; dr = next) { | | | |
596 | next = dr->dr_next; | | | |
597 | designator_free(dr); | | | |
598 | } | | | |
599 | | | | |
600 | bl->bl_designation.dn_head = NULL; | | | |
601 | bl->bl_designation.dn_tail = NULL; | | | |
602 | } | | | |
603 | | | | |
604 | | | | |
605 | static const type_t * | | 593 | static const type_t * |
606 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) | | 594 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) |
607 | { | | 595 | { |
608 | | | 596 | |
609 | if (bl->bl_next_member == NULL) { | | 597 | if (bl->bl_next_member == NULL) { |
610 | /* too many struct/union initializers */ | | 598 | /* too many struct/union initializers */ |
611 | error(172); | | 599 | error(172); |
612 | return NULL; | | 600 | return NULL; |
613 | } | | 601 | } |
614 | | | 602 | |
615 | lint_assert(!is_unnamed(bl->bl_next_member)); | | 603 | lint_assert(!is_unnamed(bl->bl_next_member)); |
616 | return sym_type(bl->bl_next_member); | | 604 | return sym_type(bl->bl_next_member); |
617 | } | | 605 | } |
| @@ -837,56 +825,49 @@ initialization_end_brace_level(struct in | | | @@ -837,56 +825,49 @@ initialization_end_brace_level(struct in |
837 | { | | 825 | { |
838 | struct brace_level *bl; | | 826 | struct brace_level *bl; |
839 | | | 827 | |
840 | if (in->in_err) | | 828 | if (in->in_err) |
841 | return; | | 829 | return; |
842 | | | 830 | |
843 | debug_enter(); | | 831 | debug_enter(); |
844 | | | 832 | |
845 | initialization_set_size_of_unknown_array(in); | | 833 | initialization_set_size_of_unknown_array(in); |
846 | | | 834 | |
847 | bl = in->in_brace_level; | | 835 | bl = in->in_brace_level; |
848 | in->in_brace_level = bl->bl_enclosing; | | 836 | in->in_brace_level = bl->bl_enclosing; |
849 | brace_level_free(bl); | | 837 | brace_level_free(bl); |
| | | 838 | bl = in->in_brace_level; |
850 | | | 839 | |
851 | if (in->in_brace_level != NULL) { | | 840 | if (bl != NULL) |
852 | brace_level_advance(in->in_brace_level); | | 841 | brace_level_advance(bl); |
853 | brace_level_remove_designation(in->in_brace_level); | | 842 | if (bl != NULL) |
854 | } | | 843 | designation_reset(&bl->bl_designation); |
855 | | | 844 | |
856 | initialization_debug(in); | | 845 | initialization_debug(in); |
857 | debug_leave(); | | 846 | debug_leave(); |
858 | } | | 847 | } |
859 | | | 848 | |
860 | static void | | 849 | static void |
861 | initialization_add_designator(struct initialization *in, | | 850 | initialization_add_designator(struct initialization *in, |
862 | const char *name, size_t subscript) | | 851 | const char *name, size_t subscript) |
863 | { | | 852 | { |
864 | | | 853 | |
865 | if (in->in_err) | | 854 | if (in->in_err) |
866 | return; | | 855 | return; |
867 | | | 856 | |
868 | lint_assert(in->in_brace_level != NULL); | | 857 | lint_assert(in->in_brace_level != NULL); |
869 | designation_add(&in->in_brace_level->bl_designation, name, subscript); | | 858 | designation_add(&in->in_brace_level->bl_designation, name, subscript); |
870 | } | | 859 | } |
871 | | | 860 | |
872 | static void | | | |
873 | initialization_remove_designation(struct initialization *in) | | | |
874 | { | | | |
875 | | | | |
876 | if (in->in_brace_level != NULL) | | | |
877 | brace_level_remove_designation(in->in_brace_level); | | | |
878 | } | | | |
879 | | | | |
880 | /* | | 861 | /* |
881 | * An object with automatic storage duration that has a single initializer | | 862 | * An object with automatic storage duration that has a single initializer |
882 | * expression without braces and is not an array is initialized by delegating | | 863 | * expression without braces and is not an array is initialized by delegating |
883 | * to the ASSIGN operator. | | 864 | * to the ASSIGN operator. |
884 | */ | | 865 | */ |
885 | static bool | | 866 | static bool |
886 | initialization_expr_using_assign(struct initialization *in, tnode_t *rn) | | 867 | initialization_expr_using_assign(struct initialization *in, tnode_t *rn) |
887 | { | | 868 | { |
888 | tnode_t *ln, *tn; | | 869 | tnode_t *ln, *tn; |
889 | | | 870 | |
890 | if (!has_automatic_storage_duration(in->in_sym)) | | 871 | if (!has_automatic_storage_duration(in->in_sym)) |
891 | return false; | | 872 | return false; |
892 | if (in->in_brace_level != NULL) | | 873 | if (in->in_brace_level != NULL) |
| @@ -941,78 +922,81 @@ initialization_init_array_using_string(s | | | @@ -941,78 +922,81 @@ initialization_init_array_using_string(s |
941 | strg->st_len + 1); | | 922 | strg->st_len + 1); |
942 | } | | 923 | } |
943 | | | 924 | |
944 | return true; | | 925 | return true; |
945 | } | | 926 | } |
946 | | | 927 | |
947 | /* | | 928 | /* |
948 | * Initialize a single sub-object as part of the currently ongoing | | 929 | * Initialize a single sub-object as part of the currently ongoing |
949 | * initialization. | | 930 | * initialization. |
950 | */ | | 931 | */ |
951 | static void | | 932 | static void |
952 | initialization_expr(struct initialization *in, tnode_t *tn) | | 933 | initialization_expr(struct initialization *in, tnode_t *tn) |
953 | { | | 934 | { |
| | | 935 | struct brace_level *bl; |
954 | const type_t *tp; | | 936 | const type_t *tp; |
955 | | | 937 | |
956 | if (in->in_err) | | 938 | if (in->in_err) |
957 | return; | | 939 | return; |
958 | | | 940 | |
959 | if (in->in_brace_level != NULL && | | 941 | bl = in->in_brace_level; |
960 | in->in_brace_level->bl_omitted_braces) | | 942 | if (bl != NULL && bl->bl_omitted_braces) |
961 | return; | | 943 | return; |
962 | | | 944 | |
963 | debug_enter(); | | 945 | debug_enter(); |
964 | | | 946 | |
965 | if (tn == NULL) | | 947 | if (tn == NULL) |
966 | goto advance; | | 948 | goto advance; |
967 | if (initialization_expr_using_assign(in, tn)) | | 949 | if (initialization_expr_using_assign(in, tn)) |
968 | goto done; | | 950 | goto done; |
969 | if (initialization_init_array_using_string(in, tn)) | | 951 | if (initialization_init_array_using_string(in, tn)) |
970 | goto advance; | | 952 | goto advance; |
971 | | | 953 | |
972 | if (in->in_brace_level != NULL) | | 954 | if (bl != NULL) |
973 | brace_level_apply_designation(in->in_brace_level); | | 955 | brace_level_apply_designation(bl); |
974 | tp = initialization_sub_type(in); | | 956 | tp = initialization_sub_type(in); |
975 | if (tp == NULL) | | 957 | if (tp == NULL) |
976 | goto done; | | 958 | goto done; |
977 | | | 959 | |
978 | if (in->in_brace_level == NULL && !is_scalar(tp->t_tspec)) { | | 960 | if (bl == NULL && !is_scalar(tp->t_tspec)) { |
979 | /* {}-enclosed initializer required */ | | 961 | /* {}-enclosed initializer required */ |
980 | error(181); | | 962 | error(181); |
981 | goto done; | | 963 | goto done; |
982 | } | | 964 | } |
983 | | | 965 | |
984 | /* | | 966 | /* |
985 | * Hack to accept initializations with omitted braces, see | | 967 | * Hack to accept initializations with omitted braces, see |
986 | * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and | | 968 | * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and |
987 | * Clang already warn about this at level -Wall, there is no point | | 969 | * Clang already warn about this at level -Wall, there is no point |
988 | * in letting lint check this again. | | 970 | * in letting lint check this again. |
989 | */ | | 971 | */ |
990 | if (is_scalar(tn->tn_type->t_tspec) && | | 972 | if (is_scalar(tn->tn_type->t_tspec) && |
991 | tp->t_tspec == ARRAY && | | 973 | tp->t_tspec == ARRAY && |
992 | in->in_brace_level != NULL) { | | 974 | bl != NULL) { |
993 | in->in_brace_level->bl_omitted_braces = true; | | 975 | bl->bl_omitted_braces = true; |
994 | goto done; | | 976 | goto done; |
995 | } | | 977 | } |
996 | | | 978 | |
997 | debug_step("expecting '%s', expression has '%s'", | | 979 | debug_step("expecting '%s', expression has '%s'", |
998 | type_name(tp), type_name(tn->tn_type)); | | 980 | type_name(tp), type_name(tn->tn_type)); |
999 | check_init_expr(tp, in->in_sym, tn); | | 981 | check_init_expr(tp, in->in_sym, tn); |
1000 | | | 982 | |
1001 | advance: | | 983 | advance: |
1002 | if (in->in_brace_level != NULL) | | 984 | if (bl != NULL) |
1003 | brace_level_advance(in->in_brace_level); | | 985 | brace_level_advance(bl); |
1004 | done: | | 986 | done: |
1005 | initialization_remove_designation(in); | | 987 | if (bl != NULL) |
| | | 988 | designation_reset(&bl->bl_designation); |
| | | 989 | |
1006 | initialization_debug(in); | | 990 | initialization_debug(in); |
1007 | debug_leave(); | | 991 | debug_leave(); |
1008 | } | | 992 | } |
1009 | | | 993 | |
1010 | | | 994 | |
1011 | static struct initialization *init; | | 995 | static struct initialization *init; |
1012 | | | 996 | |
1013 | | | 997 | |
1014 | static struct initialization * | | 998 | static struct initialization * |
1015 | current_init(void) | | 999 | current_init(void) |
1016 | { | | 1000 | { |
1017 | | | 1001 | |
1018 | lint_assert(init != NULL); | | 1002 | lint_assert(init != NULL); |