| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.55 2021/01/01 20:02:56 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,30 +27,29 @@ | | | @@ -27,30 +27,29 @@ |
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.54 2021/01/01 19:28:51 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.55 2021/01/01 20:02:56 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <ctype.h> | | | |
44 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
45 | #include <string.h> | | 44 | #include <string.h> |
46 | | | 45 | |
47 | #include "lint1.h" | | 46 | #include "lint1.h" |
48 | | | 47 | |
49 | | | 48 | |
50 | /* | | 49 | /* |
51 | * Type of stack which is used for initialisation of aggregate types. | | 50 | * Type of stack which is used for initialisation of aggregate types. |
52 | * | | 51 | * |
53 | * XXX: Since C99, a stack is an inappropriate data structure for modelling | | 52 | * XXX: Since C99, a stack is an inappropriate data structure for modelling |
54 | * an initialization, since the designators don't have to be listed in a | | 53 | * an initialization, since the designators don't have to be listed in a |
55 | * particular order and can designate parts of sub-objects. The member names | | 54 | * particular order and can designate parts of sub-objects. The member names |
56 | * of non-leaf structs may thus appear repeatedly, as demonstrated in | | 55 | * of non-leaf structs may thus appear repeatedly, as demonstrated in |
| @@ -64,26 +63,39 @@ __RCSID("$NetBSD: init.c,v 1.54 2021/01/ | | | @@ -64,26 +63,39 @@ __RCSID("$NetBSD: init.c,v 1.54 2021/01/ |
64 | * selected examples. | | 63 | * selected examples. |
65 | */ | | 64 | */ |
66 | typedef struct istk { | | 65 | typedef struct istk { |
67 | type_t *i_type; /* type of initialisation */ | | 66 | type_t *i_type; /* type of initialisation */ |
68 | type_t *i_subt; /* type of next level */ | | 67 | type_t *i_subt; /* type of next level */ |
69 | u_int i_brace : 1; /* need } for pop */ | | 68 | u_int i_brace : 1; /* need } for pop */ |
70 | u_int i_nolimit : 1; /* incomplete array type */ | | 69 | u_int i_nolimit : 1; /* incomplete array type */ |
71 | u_int i_namedmem : 1; /* has c9x named members */ | | 70 | u_int i_namedmem : 1; /* has c9x named members */ |
72 | sym_t *i_mem; /* next structure member */ | | 71 | sym_t *i_mem; /* next structure member */ |
73 | int i_remaining; /* # of remaining elements */ | | 72 | int i_remaining; /* # of remaining elements */ |
74 | struct istk *i_next; /* previous level */ | | 73 | struct istk *i_next; /* previous level */ |
75 | } istk_t; | | 74 | } istk_t; |
76 | | | 75 | |
| | | 76 | /* |
| | | 77 | * The names for a nested C99 initialization designator, in a circular list. |
| | | 78 | * |
| | | 79 | * Example: |
| | | 80 | * struct stat st = { |
| | | 81 | * .st_size = 123, |
| | | 82 | * .st_mtim.tv_sec = 45, |
| | | 83 | * .st_mtim.tv_nsec |
| | | 84 | * }; |
| | | 85 | * |
| | | 86 | * During initialization, this list first contains ["st_size"], then |
| | | 87 | * ["st_mtim", "tv_sec"], then ["st_mtim", "tv_nsec"]. |
| | | 88 | */ |
77 | typedef struct namlist { | | 89 | typedef struct namlist { |
78 | const char *n_name; | | 90 | const char *n_name; |
79 | struct namlist *n_prev; | | 91 | struct namlist *n_prev; |
80 | struct namlist *n_next; | | 92 | struct namlist *n_next; |
81 | } namlist_t; | | 93 | } namlist_t; |
82 | | | 94 | |
83 | | | 95 | |
84 | /* | | 96 | /* |
85 | * initerr is set as soon as a fatal error occurred in an initialisation. | | 97 | * initerr is set as soon as a fatal error occurred in an initialisation. |
86 | * The effect is that the rest of the initialisation is ignored (parsed | | 98 | * The effect is that the rest of the initialisation is ignored (parsed |
87 | * by yacc, expression trees built, but no initialisation takes place). | | 99 | * by yacc, expression trees built, but no initialisation takes place). |
88 | */ | | 100 | */ |
89 | int initerr; | | 101 | int initerr; |
| @@ -134,26 +146,41 @@ pop_member(void) | | | @@ -134,26 +146,41 @@ pop_member(void) |
134 | DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); | | 146 | DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); |
135 | if (namedmem->n_next == namedmem) { | | 147 | if (namedmem->n_next == namedmem) { |
136 | free(namedmem); | | 148 | free(namedmem); |
137 | namedmem = NULL; | | 149 | namedmem = NULL; |
138 | } else { | | 150 | } else { |
139 | namlist_t *nam = namedmem; | | 151 | namlist_t *nam = namedmem; |
140 | namedmem = namedmem->n_next; | | 152 | namedmem = namedmem->n_next; |
141 | nam->n_prev->n_next = nam->n_next; | | 153 | nam->n_prev->n_next = nam->n_next; |
142 | nam->n_next->n_prev = nam->n_prev; | | 154 | nam->n_next->n_prev = nam->n_prev; |
143 | free(nam); | | 155 | free(nam); |
144 | } | | 156 | } |
145 | } | | 157 | } |
146 | | | 158 | |
| | | 159 | static void |
| | | 160 | named_member_dprint(void) |
| | | 161 | { |
| | | 162 | namlist_t *name; |
| | | 163 | |
| | | 164 | if (namedmem == NULL) |
| | | 165 | return; |
| | | 166 | name = namedmem; |
| | | 167 | DPRINTF(("named member:")); |
| | | 168 | do { |
| | | 169 | DPRINTF((" %s", name->n_name)); |
| | | 170 | name = name->n_next; |
| | | 171 | } while (name != namedmem); |
| | | 172 | DPRINTF(("\n")); |
| | | 173 | } |
147 | | | 174 | |
148 | /* | | 175 | /* |
149 | * Initialize the initialisation stack by putting an entry for the variable | | 176 | * Initialize the initialisation stack by putting an entry for the variable |
150 | * which is to be initialized on it. | | 177 | * which is to be initialized on it. |
151 | */ | | 178 | */ |
152 | void | | 179 | void |
153 | initstack_init(void) | | 180 | initstack_init(void) |
154 | { | | 181 | { |
155 | istk_t *istk; | | 182 | istk_t *istk; |
156 | | | 183 | |
157 | if (initerr) | | 184 | if (initerr) |
158 | return; | | 185 | return; |
159 | | | 186 | |
| @@ -536,26 +563,28 @@ mkinit(tnode_t *tn) | | | @@ -536,26 +563,28 @@ mkinit(tnode_t *tn) |
536 | ptrdiff_t offs; | | 563 | ptrdiff_t offs; |
537 | sym_t *sym; | | 564 | sym_t *sym; |
538 | tspec_t lt, rt; | | 565 | tspec_t lt, rt; |
539 | tnode_t *ln; | | 566 | tnode_t *ln; |
540 | struct mbl *tmem; | | 567 | struct mbl *tmem; |
541 | scl_t sc; | | 568 | scl_t sc; |
542 | #ifdef DEBUG | | 569 | #ifdef DEBUG |
543 | char buf[64], sbuf[64]; | | 570 | char buf[64], sbuf[64]; |
544 | #endif | | 571 | #endif |
545 | | | 572 | |
546 | DPRINTF(("%s: type=%s, value=%s\n", __func__, | | 573 | DPRINTF(("%s: type=%s, value=%s\n", __func__, |
547 | tyname(buf, sizeof(buf), tn->tn_type), | | 574 | tyname(buf, sizeof(buf), tn->tn_type), |
548 | print_tnode(sbuf, sizeof(sbuf), tn))); | | 575 | print_tnode(sbuf, sizeof(sbuf), tn))); |
| | | 576 | named_member_dprint(); |
| | | 577 | |
549 | if (initerr || tn == NULL) | | 578 | if (initerr || tn == NULL) |
550 | return; | | 579 | return; |
551 | | | 580 | |
552 | sc = initsym->s_scl; | | 581 | sc = initsym->s_scl; |
553 | | | 582 | |
554 | /* | | 583 | /* |
555 | * Do not test for automatic aggregate initialisation. If the | | 584 | * Do not test for automatic aggregate initialisation. If the |
556 | * initializer starts with a brace we have the warning already. | | 585 | * initializer starts with a brace we have the warning already. |
557 | * If not, an error will be printed that the initializer must | | 586 | * If not, an error will be printed that the initializer must |
558 | * be enclosed by braces. | | 587 | * be enclosed by braces. |
559 | */ | | 588 | */ |
560 | | | 589 | |
561 | /* | | 590 | /* |