| @@ -1,699 +1,712 @@ | | | @@ -1,699 +1,712 @@ |
1 | /* $NetBSD: init.c,v 1.53 2021/01/01 19:15:58 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.54 2021/01/01 19:28:51 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. |
15 | * 3. All advertising materials mentioning features or use of this software | | 15 | * 3. All advertising materials mentioning features or use of this software |
16 | * must display the following acknowledgement: | | 16 | * must display the following acknowledgement: |
17 | * This product includes software developed by Jochen Pohl for | | 17 | * This product includes software developed by Jochen Pohl for |
18 | * The NetBSD Project. | | 18 | * The NetBSD Project. |
19 | * 4. The name of the author may not be used to endorse or promote products | | 19 | * 4. The name of the author may not be used to endorse or promote products |
20 | * derived from this software without specific prior written permission. | | 20 | * derived from this software without specific prior written permission. |
21 | * | | 21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
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.53 2021/01/01 19:15:58 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <ctype.h> | | 43 | #include <ctype.h> |
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 | * Type of stack which is used for initialisation of aggregate types. | | 51 | * Type of stack which is used for initialisation of aggregate types. |
| | | 52 | * |
| | | 53 | * 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 |
| | | 55 | * particular order and can designate parts of sub-objects. The member names |
| | | 56 | * of non-leaf structs may thus appear repeatedly, as demonstrated in |
| | | 57 | * d_init_pop_member.c. |
| | | 58 | * |
| | | 59 | * XXX: During initialization, there may be members of the top-level struct |
| | | 60 | * that are partially initialized. The simple i_remaining cannot model this |
| | | 61 | * appropriately. |
| | | 62 | * |
| | | 63 | * See C99 6.7.8, which spans 6 pages full of tricky details and carefully |
| | | 64 | * selected examples. |
52 | */ | | 65 | */ |
53 | typedef struct istk { | | 66 | typedef struct istk { |
54 | type_t *i_type; /* type of initialisation */ | | 67 | type_t *i_type; /* type of initialisation */ |
55 | type_t *i_subt; /* type of next level */ | | 68 | type_t *i_subt; /* type of next level */ |
56 | u_int i_brace : 1; /* need } for pop */ | | 69 | u_int i_brace : 1; /* need } for pop */ |
57 | u_int i_nolimit : 1; /* incomplete array type */ | | 70 | u_int i_nolimit : 1; /* incomplete array type */ |
58 | u_int i_namedmem : 1; /* has c9x named members */ | | 71 | u_int i_namedmem : 1; /* has c9x named members */ |
59 | sym_t *i_mem; /* next structure member */ | | 72 | sym_t *i_mem; /* next structure member */ |
60 | int i_remaining; /* # of remaining elements */ | | 73 | int i_remaining; /* # of remaining elements */ |
61 | struct istk *i_next; /* previous level */ | | 74 | struct istk *i_next; /* previous level */ |
62 | } istk_t; | | 75 | } istk_t; |
63 | | | 76 | |
64 | typedef struct namlist { | | 77 | typedef struct namlist { |
65 | const char *n_name; | | 78 | const char *n_name; |
66 | struct namlist *n_prev; | | 79 | struct namlist *n_prev; |
67 | struct namlist *n_next; | | 80 | struct namlist *n_next; |
68 | } namlist_t; | | 81 | } namlist_t; |
69 | | | 82 | |
70 | | | 83 | |
71 | /* | | 84 | /* |
72 | * initerr is set as soon as a fatal error occurred in an initialisation. | | 85 | * initerr is set as soon as a fatal error occurred in an initialisation. |
73 | * The effect is that the rest of the initialisation is ignored (parsed | | 86 | * The effect is that the rest of the initialisation is ignored (parsed |
74 | * by yacc, expression trees built, but no initialisation takes place). | | 87 | * by yacc, expression trees built, but no initialisation takes place). |
75 | */ | | 88 | */ |
76 | int initerr; | | 89 | int initerr; |
77 | | | 90 | |
78 | /* Pointer to the symbol which is to be initialized. */ | | 91 | /* Pointer to the symbol which is to be initialized. */ |
79 | sym_t *initsym; | | 92 | sym_t *initsym; |
80 | | | 93 | |
81 | /* Points to the top element of the initialisation stack. */ | | 94 | /* Points to the top element of the initialisation stack. */ |
82 | istk_t *initstk; | | 95 | istk_t *initstk; |
83 | | | 96 | |
84 | /* Points to a c9x named member; */ | | 97 | /* Points to a c9x named member; */ |
85 | namlist_t *namedmem = NULL; | | 98 | namlist_t *namedmem = NULL; |
86 | | | 99 | |
87 | | | 100 | |
88 | static int initstack_string(tnode_t *); | | 101 | static int initstack_string(tnode_t *); |
89 | | | 102 | |
90 | #ifndef DEBUG | | 103 | #ifndef DEBUG |
91 | #define DPRINTF(a) | | 104 | #define DPRINTF(a) |
92 | #else | | 105 | #else |
93 | #define DPRINTF(a) printf a | | 106 | #define DPRINTF(a) printf a |
94 | #endif | | 107 | #endif |
95 | | | 108 | |
96 | void | | 109 | void |
97 | push_member(sbuf_t *sb) | | 110 | push_member(sbuf_t *sb) |
98 | { | | 111 | { |
99 | namlist_t *nam = xcalloc(1, sizeof (namlist_t)); | | 112 | namlist_t *nam = xcalloc(1, sizeof (namlist_t)); |
100 | nam->n_name = sb->sb_name; | | 113 | nam->n_name = sb->sb_name; |
101 | DPRINTF(("%s: %s %p\n", __func__, nam->n_name, nam)); | | 114 | DPRINTF(("%s: %s %p\n", __func__, nam->n_name, nam)); |
102 | if (namedmem == NULL) { | | 115 | if (namedmem == NULL) { |
103 | /* | | 116 | /* |
104 | * XXX: Why is this a circular list? | | 117 | * XXX: Why is this a circular list? |
105 | * XXX: Why is this a doubly-linked list? | | 118 | * XXX: Why is this a doubly-linked list? |
106 | * A simple stack should suffice. | | 119 | * A simple stack should suffice. |
107 | */ | | 120 | */ |
108 | nam->n_prev = nam->n_next = nam; | | 121 | nam->n_prev = nam->n_next = nam; |
109 | namedmem = nam; | | 122 | namedmem = nam; |
110 | } else { | | 123 | } else { |
111 | namedmem->n_prev->n_next = nam; | | 124 | namedmem->n_prev->n_next = nam; |
112 | nam->n_prev = namedmem->n_prev; | | 125 | nam->n_prev = namedmem->n_prev; |
113 | nam->n_next = namedmem; | | 126 | nam->n_next = namedmem; |
114 | namedmem->n_prev = nam; | | 127 | namedmem->n_prev = nam; |
115 | } | | 128 | } |
116 | } | | 129 | } |
117 | | | 130 | |
118 | static void | | 131 | static void |
119 | pop_member(void) | | 132 | pop_member(void) |
120 | { | | 133 | { |
121 | DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); | | 134 | DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); |
122 | if (namedmem->n_next == namedmem) { | | 135 | if (namedmem->n_next == namedmem) { |
123 | free(namedmem); | | 136 | free(namedmem); |
124 | namedmem = NULL; | | 137 | namedmem = NULL; |
125 | } else { | | 138 | } else { |
126 | namlist_t *nam = namedmem; | | 139 | namlist_t *nam = namedmem; |
127 | namedmem = namedmem->n_next; | | 140 | namedmem = namedmem->n_next; |
128 | nam->n_prev->n_next = nam->n_next; | | 141 | nam->n_prev->n_next = nam->n_next; |
129 | nam->n_next->n_prev = nam->n_prev; | | 142 | nam->n_next->n_prev = nam->n_prev; |
130 | free(nam); | | 143 | free(nam); |
131 | } | | 144 | } |
132 | } | | 145 | } |
133 | | | 146 | |
134 | | | 147 | |
135 | /* | | 148 | /* |
136 | * Initialize the initialisation stack by putting an entry for the variable | | 149 | * Initialize the initialisation stack by putting an entry for the variable |
137 | * which is to be initialized on it. | | 150 | * which is to be initialized on it. |
138 | */ | | 151 | */ |
139 | void | | 152 | void |
140 | initstack_init(void) | | 153 | initstack_init(void) |
141 | { | | 154 | { |
142 | istk_t *istk; | | 155 | istk_t *istk; |
143 | | | 156 | |
144 | if (initerr) | | 157 | if (initerr) |
145 | return; | | 158 | return; |
146 | | | 159 | |
147 | /* free memory used in last initialisation */ | | 160 | /* free memory used in last initialisation */ |
148 | while ((istk = initstk) != NULL) { | | 161 | while ((istk = initstk) != NULL) { |
149 | initstk = istk->i_next; | | 162 | initstk = istk->i_next; |
150 | free(istk); | | 163 | free(istk); |
151 | } | | 164 | } |
152 | | | 165 | |
153 | DPRINTF(("%s\n", __func__)); | | 166 | DPRINTF(("%s\n", __func__)); |
154 | | | 167 | |
155 | /* | | 168 | /* |
156 | * If the type which is to be initialized is an incomplete type, | | 169 | * If the type which is to be initialized is an incomplete type, |
157 | * it must be duplicated. | | 170 | * it must be duplicated. |
158 | */ | | 171 | */ |
159 | if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type)) | | 172 | if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type)) |
160 | initsym->s_type = duptyp(initsym->s_type); | | 173 | initsym->s_type = duptyp(initsym->s_type); |
161 | | | 174 | |
162 | istk = initstk = xcalloc(1, sizeof (istk_t)); | | 175 | istk = initstk = xcalloc(1, sizeof (istk_t)); |
163 | istk->i_subt = initsym->s_type; | | 176 | istk->i_subt = initsym->s_type; |
164 | istk->i_remaining = 1; | | 177 | istk->i_remaining = 1; |
165 | } | | 178 | } |
166 | | | 179 | |
167 | static void | | 180 | static void |
168 | initstack_pop_item(void) | | 181 | initstack_pop_item(void) |
169 | { | | 182 | { |
170 | #ifdef DEBUG | | 183 | #ifdef DEBUG |
171 | char buf[64]; | | 184 | char buf[64]; |
172 | #endif | | 185 | #endif |
173 | istk_t *istk; | | 186 | istk_t *istk; |
174 | sym_t *m; | | 187 | sym_t *m; |
175 | | | 188 | |
176 | istk = initstk; | | 189 | istk = initstk; |
177 | DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__, | | 190 | DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__, |
178 | tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), | | 191 | tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), |
179 | istk->i_brace, istk->i_remaining, istk->i_namedmem)); | | 192 | istk->i_brace, istk->i_remaining, istk->i_namedmem)); |
180 | | | 193 | |
181 | initstk = istk->i_next; | | 194 | initstk = istk->i_next; |
182 | free(istk); | | 195 | free(istk); |
183 | istk = initstk; | | 196 | istk = initstk; |
184 | lint_assert(istk != NULL); | | 197 | lint_assert(istk != NULL); |
185 | | | 198 | |
186 | DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__, | | 199 | DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__, |
187 | tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), | | 200 | tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt), |
188 | istk->i_brace, istk->i_remaining, istk->i_namedmem)); | | 201 | istk->i_brace, istk->i_remaining, istk->i_namedmem)); |
189 | | | 202 | |
190 | istk->i_remaining--; | | 203 | istk->i_remaining--; |
191 | lint_assert(istk->i_remaining >= 0); | | 204 | lint_assert(istk->i_remaining >= 0); |
192 | | | 205 | |
193 | DPRINTF(("%s: top remaining=%d rhs.name=%s\n", __func__, | | 206 | DPRINTF(("%s: top remaining=%d rhs.name=%s\n", __func__, |
194 | istk->i_remaining, namedmem ? namedmem->n_name : "*null*")); | | 207 | istk->i_remaining, namedmem ? namedmem->n_name : "*null*")); |
195 | | | 208 | |
196 | if (istk->i_remaining >= 0 && namedmem != NULL) { | | 209 | if (istk->i_remaining >= 0 && namedmem != NULL) { |
197 | | | 210 | |
198 | DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n", | | 211 | DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n", |
199 | __func__, istk->i_remaining, | | 212 | __func__, istk->i_remaining, |
200 | tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name)); | | 213 | tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name)); |
201 | | | 214 | |
202 | for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { | | 215 | for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { |
203 | DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__, | | 216 | DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__, |
204 | m->s_name, namedmem->n_name)); | | 217 | m->s_name, namedmem->n_name)); |
205 | if (m->s_bitfield && m->s_name == unnamed) | | 218 | if (m->s_bitfield && m->s_name == unnamed) |
206 | continue; | | 219 | continue; |
207 | if (strcmp(m->s_name, namedmem->n_name) == 0) { | | 220 | if (strcmp(m->s_name, namedmem->n_name) == 0) { |
208 | istk->i_subt = m->s_type; | | 221 | istk->i_subt = m->s_type; |
209 | istk->i_remaining++; | | 222 | istk->i_remaining++; |
210 | pop_member(); | | 223 | pop_member(); |
211 | return; | | 224 | return; |
212 | } | | 225 | } |
213 | } | | 226 | } |
214 | /* undefined struct/union member: %s */ | | 227 | /* undefined struct/union member: %s */ |
215 | error(101, namedmem->n_name); | | 228 | error(101, namedmem->n_name); |
216 | DPRINTF(("%s: end rhs.name=%s\n", __func__, namedmem->n_name)); | | 229 | DPRINTF(("%s: end rhs.name=%s\n", __func__, namedmem->n_name)); |
217 | pop_member(); | | 230 | pop_member(); |
218 | istk->i_namedmem = 1; | | 231 | istk->i_namedmem = 1; |
219 | return; | | 232 | return; |
220 | } | | 233 | } |
221 | /* | | 234 | /* |
222 | * If the removed element was a structure member, we must go | | 235 | * If the removed element was a structure member, we must go |
223 | * to the next structure member. | | 236 | * to the next structure member. |
224 | */ | | 237 | */ |
225 | if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT && | | 238 | if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT && |
226 | !istk->i_namedmem) { | | 239 | !istk->i_namedmem) { |
227 | do { | | 240 | do { |
228 | m = istk->i_mem = istk->i_mem->s_next; | | 241 | m = istk->i_mem = istk->i_mem->s_next; |
229 | lint_assert(m != NULL); | | 242 | lint_assert(m != NULL); |
230 | DPRINTF(("%s: pop %s\n", __func__, m->s_name)); | | 243 | DPRINTF(("%s: pop %s\n", __func__, m->s_name)); |
231 | } while (m->s_bitfield && m->s_name == unnamed); | | 244 | } while (m->s_bitfield && m->s_name == unnamed); |
232 | istk->i_subt = m->s_type; | | 245 | istk->i_subt = m->s_type; |
233 | } | | 246 | } |
234 | } | | 247 | } |
235 | | | 248 | |
236 | /* | | 249 | /* |
237 | * Take all entries, including the first which requires a closing brace, | | 250 | * Take all entries, including the first which requires a closing brace, |
238 | * from the stack. | | 251 | * from the stack. |
239 | */ | | 252 | */ |
240 | static void | | 253 | static void |
241 | initstack_pop_brace(void) | | 254 | initstack_pop_brace(void) |
242 | { | | 255 | { |
243 | int brace; | | 256 | int brace; |
244 | | | 257 | |
245 | DPRINTF(("%s\n", __func__)); | | 258 | DPRINTF(("%s\n", __func__)); |
246 | do { | | 259 | do { |
247 | brace = initstk->i_brace; | | 260 | brace = initstk->i_brace; |
248 | DPRINTF(("%s: loop brace=%d\n", __func__, brace)); | | 261 | DPRINTF(("%s: loop brace=%d\n", __func__, brace)); |
249 | initstack_pop_item(); | | 262 | initstack_pop_item(); |
250 | } while (!brace); | | 263 | } while (!brace); |
251 | DPRINTF(("%s: done\n", __func__)); | | 264 | DPRINTF(("%s: done\n", __func__)); |
252 | } | | 265 | } |
253 | | | 266 | |
254 | /* | | 267 | /* |
255 | * Take all entries which cannot be used for further initializers from the | | 268 | * Take all entries which cannot be used for further initializers from the |
256 | * stack, but do this only if they do not require a closing brace. | | 269 | * stack, but do this only if they do not require a closing brace. |
257 | */ | | 270 | */ |
258 | static void | | 271 | static void |
259 | initstack_pop_nobrace(void) | | 272 | initstack_pop_nobrace(void) |
260 | { | | 273 | { |
261 | | | 274 | |
262 | DPRINTF(("%s\n", __func__)); | | 275 | DPRINTF(("%s\n", __func__)); |
263 | while (!initstk->i_brace && initstk->i_remaining == 0 && | | 276 | while (!initstk->i_brace && initstk->i_remaining == 0 && |
264 | !initstk->i_nolimit) | | 277 | !initstk->i_nolimit) |
265 | initstack_pop_item(); | | 278 | initstack_pop_item(); |
266 | DPRINTF(("%s: done\n", __func__)); | | 279 | DPRINTF(("%s: done\n", __func__)); |
267 | } | | 280 | } |
268 | | | 281 | |
269 | static void | | 282 | static void |
270 | initstack_push(void) | | 283 | initstack_push(void) |
271 | { | | 284 | { |
272 | #ifdef DEBUG | | 285 | #ifdef DEBUG |
273 | char buf[64]; | | 286 | char buf[64]; |
274 | #endif | | 287 | #endif |
275 | istk_t *istk, *inxt; | | 288 | istk_t *istk, *inxt; |
276 | int cnt; | | 289 | int cnt; |
277 | sym_t *m; | | 290 | sym_t *m; |
278 | | | 291 | |
279 | istk = initstk; | | 292 | istk = initstk; |
280 | | | 293 | |
281 | /* Extend an incomplete array type by one element */ | | 294 | /* Extend an incomplete array type by one element */ |
282 | if (istk->i_remaining == 0) { | | 295 | if (istk->i_remaining == 0) { |
283 | DPRINTF(("%s(extend) %s\n", __func__, | | 296 | DPRINTF(("%s(extend) %s\n", __func__, |
284 | tyname(buf, sizeof(buf), istk->i_type))); | | 297 | tyname(buf, sizeof(buf), istk->i_type))); |
285 | /* | | 298 | /* |
286 | * Inside of other aggregate types must not be an incomplete | | 299 | * Inside of other aggregate types must not be an incomplete |
287 | * type. | | 300 | * type. |
288 | */ | | 301 | */ |
289 | lint_assert(istk->i_next->i_next == NULL); | | 302 | lint_assert(istk->i_next->i_next == NULL); |
290 | istk->i_remaining = 1; | | 303 | istk->i_remaining = 1; |
291 | lint_assert(istk->i_type->t_tspec == ARRAY); | | 304 | lint_assert(istk->i_type->t_tspec == ARRAY); |
292 | istk->i_type->t_dim++; | | 305 | istk->i_type->t_dim++; |
293 | setcomplete(istk->i_type, 1); | | 306 | setcomplete(istk->i_type, 1); |
294 | } | | 307 | } |
295 | | | 308 | |
296 | lint_assert(istk->i_remaining > 0); | | 309 | lint_assert(istk->i_remaining > 0); |
297 | lint_assert(istk->i_type == NULL || | | 310 | lint_assert(istk->i_type == NULL || |
298 | !tspec_is_scalar(istk->i_type->t_tspec)); | | 311 | !tspec_is_scalar(istk->i_type->t_tspec)); |
299 | | | 312 | |
300 | initstk = xcalloc(1, sizeof (istk_t)); | | 313 | initstk = xcalloc(1, sizeof (istk_t)); |
301 | initstk->i_next = istk; | | 314 | initstk->i_next = istk; |
302 | initstk->i_type = istk->i_subt; | | 315 | initstk->i_type = istk->i_subt; |
303 | lint_assert(initstk->i_type->t_tspec != FUNC); | | 316 | lint_assert(initstk->i_type->t_tspec != FUNC); |
304 | | | 317 | |
305 | again: | | 318 | again: |
306 | istk = initstk; | | 319 | istk = initstk; |
307 | | | 320 | |
308 | DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type))); | | 321 | DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type))); |
309 | switch (istk->i_type->t_tspec) { | | 322 | switch (istk->i_type->t_tspec) { |
310 | case ARRAY: | | 323 | case ARRAY: |
311 | if (namedmem) { | | 324 | if (namedmem) { |
312 | DPRINTF(("%s: ARRAY %s brace=%d\n", __func__, | | 325 | DPRINTF(("%s: ARRAY %s brace=%d\n", __func__, |
313 | namedmem->n_name, istk->i_brace)); | | 326 | namedmem->n_name, istk->i_brace)); |
314 | goto pop; | | 327 | goto pop; |
315 | } else if (istk->i_next->i_namedmem) { | | 328 | } else if (istk->i_next->i_namedmem) { |
316 | istk->i_brace = 1; | | 329 | istk->i_brace = 1; |
317 | DPRINTF(("%s ARRAY brace=%d, namedmem=%d\n", __func__, | | 330 | DPRINTF(("%s ARRAY brace=%d, namedmem=%d\n", __func__, |
318 | istk->i_brace, istk->i_next->i_namedmem)); | | 331 | istk->i_brace, istk->i_next->i_namedmem)); |
319 | } | | 332 | } |
320 | | | 333 | |
321 | if (incompl(istk->i_type) && istk->i_next->i_next != NULL) { | | 334 | if (incompl(istk->i_type) && istk->i_next->i_next != NULL) { |
322 | /* initialisation of an incomplete type */ | | 335 | /* initialisation of an incomplete type */ |
323 | error(175); | | 336 | error(175); |
324 | initerr = 1; | | 337 | initerr = 1; |
325 | return; | | 338 | return; |
326 | } | | 339 | } |
327 | istk->i_subt = istk->i_type->t_subt; | | 340 | istk->i_subt = istk->i_type->t_subt; |
328 | istk->i_nolimit = incompl(istk->i_type); | | 341 | istk->i_nolimit = incompl(istk->i_type); |
329 | istk->i_remaining = istk->i_type->t_dim; | | 342 | istk->i_remaining = istk->i_type->t_dim; |
330 | DPRINTF(("%s: elements array %s[%d] %s\n", __func__, | | 343 | DPRINTF(("%s: elements array %s[%d] %s\n", __func__, |
331 | tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining, | | 344 | tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining, |
332 | namedmem ? namedmem->n_name : "*none*")); | | 345 | namedmem ? namedmem->n_name : "*none*")); |
333 | break; | | 346 | break; |
334 | case UNION: | | 347 | case UNION: |
335 | if (tflag) | | 348 | if (tflag) |
336 | /* initialisation of union is illegal in trad. C */ | | 349 | /* initialisation of union is illegal in trad. C */ |
337 | warning(238); | | 350 | warning(238); |
338 | /* FALLTHROUGH */ | | 351 | /* FALLTHROUGH */ |
339 | case STRUCT: | | 352 | case STRUCT: |
340 | if (incompl(istk->i_type)) { | | 353 | if (incompl(istk->i_type)) { |
341 | /* initialisation of an incomplete type */ | | 354 | /* initialisation of an incomplete type */ |
342 | error(175); | | 355 | error(175); |
343 | initerr = 1; | | 356 | initerr = 1; |
344 | return; | | 357 | return; |
345 | } | | 358 | } |
346 | cnt = 0; | | 359 | cnt = 0; |
347 | DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__, | | 360 | DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__, |
348 | tyname(buf, sizeof(buf), istk->i_type), | | 361 | tyname(buf, sizeof(buf), istk->i_type), |
349 | namedmem ? namedmem->n_name : "*none*", istk->i_namedmem)); | | 362 | namedmem ? namedmem->n_name : "*none*", istk->i_namedmem)); |
350 | for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { | | 363 | for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) { |
351 | if (m->s_bitfield && m->s_name == unnamed) | | 364 | if (m->s_bitfield && m->s_name == unnamed) |
352 | continue; | | 365 | continue; |
353 | if (namedmem != NULL) { | | 366 | if (namedmem != NULL) { |
354 | DPRINTF(("%s: named lhs.member=%s, rhs.member=%s\n", | | 367 | DPRINTF(("%s: named lhs.member=%s, rhs.member=%s\n", |
355 | __func__, m->s_name, namedmem->n_name)); | | 368 | __func__, m->s_name, namedmem->n_name)); |
356 | if (strcmp(m->s_name, namedmem->n_name) == 0) { | | 369 | if (strcmp(m->s_name, namedmem->n_name) == 0) { |
357 | cnt++; | | 370 | cnt++; |
358 | break; | | 371 | break; |
359 | } else | | 372 | } else |
360 | continue; | | 373 | continue; |
361 | } | | 374 | } |
362 | if (++cnt == 1) { | | 375 | if (++cnt == 1) { |
363 | istk->i_mem = m; | | 376 | istk->i_mem = m; |
364 | istk->i_subt = m->s_type; | | 377 | istk->i_subt = m->s_type; |
365 | } | | 378 | } |
366 | } | | 379 | } |
367 | if (namedmem != NULL) { | | 380 | if (namedmem != NULL) { |
368 | if (m == NULL) { | | 381 | if (m == NULL) { |
369 | DPRINTF(("%s: pop struct\n", __func__)); | | 382 | DPRINTF(("%s: pop struct\n", __func__)); |
370 | goto pop; | | 383 | goto pop; |
371 | } | | 384 | } |
372 | istk->i_mem = m; | | 385 | istk->i_mem = m; |
373 | istk->i_subt = m->s_type; | | 386 | istk->i_subt = m->s_type; |
374 | istk->i_namedmem = 1; | | 387 | istk->i_namedmem = 1; |
375 | DPRINTF(("%s: named name=%s\n", __func__, | | 388 | DPRINTF(("%s: named name=%s\n", __func__, |
376 | namedmem->n_name)); | | 389 | namedmem->n_name)); |
377 | pop_member(); | | 390 | pop_member(); |
378 | cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1; | | 391 | cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1; |
379 | } | | 392 | } |
380 | istk->i_brace = 1; | | 393 | istk->i_brace = 1; |
381 | DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__, | | 394 | DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__, |
382 | tyname(buf, sizeof(buf), | | 395 | tyname(buf, sizeof(buf), |
383 | istk->i_type ? istk->i_type : istk->i_subt), | | 396 | istk->i_type ? istk->i_type : istk->i_subt), |
384 | istk->i_brace)); | | 397 | istk->i_brace)); |
385 | if (cnt == 0) { | | 398 | if (cnt == 0) { |
386 | /* cannot init. struct/union with no named member */ | | 399 | /* cannot init. struct/union with no named member */ |
387 | error(179); | | 400 | error(179); |
388 | initerr = 1; | | 401 | initerr = 1; |
389 | return; | | 402 | return; |
390 | } | | 403 | } |
391 | istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1; | | 404 | istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1; |
392 | break; | | 405 | break; |
393 | default: | | 406 | default: |
394 | if (namedmem) { | | 407 | if (namedmem) { |
395 | DPRINTF(("%s: pop\n", __func__)); | | 408 | DPRINTF(("%s: pop\n", __func__)); |
396 | pop: | | 409 | pop: |
397 | inxt = initstk->i_next; | | 410 | inxt = initstk->i_next; |
398 | free(istk); | | 411 | free(istk); |
399 | initstk = inxt; | | 412 | initstk = inxt; |
400 | goto again; | | 413 | goto again; |
401 | } | | 414 | } |
402 | istk->i_remaining = 1; | | 415 | istk->i_remaining = 1; |
403 | break; | | 416 | break; |
404 | } | | 417 | } |
405 | } | | 418 | } |
406 | | | 419 | |
407 | static void | | 420 | static void |
408 | initstack_check_too_many(void) | | 421 | initstack_check_too_many(void) |
409 | { | | 422 | { |
410 | istk_t *istk; | | 423 | istk_t *istk; |
411 | | | 424 | |
412 | istk = initstk; | | 425 | istk = initstk; |
413 | | | 426 | |
414 | /* | | 427 | /* |
415 | * If a closing brace is expected we have at least one initializer | | 428 | * If a closing brace is expected we have at least one initializer |
416 | * too much. | | 429 | * too much. |
417 | */ | | 430 | */ |
418 | if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) { | | 431 | if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) { |
419 | switch (istk->i_type->t_tspec) { | | 432 | switch (istk->i_type->t_tspec) { |
420 | case ARRAY: | | 433 | case ARRAY: |
421 | /* too many array initializers, expected %d */ | | 434 | /* too many array initializers, expected %d */ |
422 | error(173, istk->i_type->t_dim); | | 435 | error(173, istk->i_type->t_dim); |
423 | break; | | 436 | break; |
424 | case STRUCT: | | 437 | case STRUCT: |
425 | case UNION: | | 438 | case UNION: |
426 | /* too many struct/union initializers */ | | 439 | /* too many struct/union initializers */ |
427 | error(172); | | 440 | error(172); |
428 | break; | | 441 | break; |
429 | default: | | 442 | default: |
430 | /* too many initializers */ | | 443 | /* too many initializers */ |
431 | error(174); | | 444 | error(174); |
432 | break; | | 445 | break; |
433 | } | | 446 | } |
434 | initerr = 1; | | 447 | initerr = 1; |
435 | } | | 448 | } |
436 | } | | 449 | } |
437 | | | 450 | |
438 | static void | | 451 | static void |
439 | initstack_next_brace(void) | | 452 | initstack_next_brace(void) |
440 | { | | 453 | { |
441 | char buf[64]; | | 454 | char buf[64]; |
442 | | | 455 | |
443 | DPRINTF(("%s\n", __func__)); | | 456 | DPRINTF(("%s\n", __func__)); |
444 | if (initstk->i_type != NULL && | | 457 | if (initstk->i_type != NULL && |
445 | tspec_is_scalar(initstk->i_type->t_tspec)) { | | 458 | tspec_is_scalar(initstk->i_type->t_tspec)) { |
446 | /* invalid initializer type %s */ | | 459 | /* invalid initializer type %s */ |
447 | error(176, tyname(buf, sizeof(buf), initstk->i_type)); | | 460 | error(176, tyname(buf, sizeof(buf), initstk->i_type)); |
448 | initerr = 1; | | 461 | initerr = 1; |
449 | } | | 462 | } |
450 | if (!initerr) | | 463 | if (!initerr) |
451 | initstack_check_too_many(); | | 464 | initstack_check_too_many(); |
452 | if (!initerr) | | 465 | if (!initerr) |
453 | initstack_push(); | | 466 | initstack_push(); |
454 | if (!initerr) { | | 467 | if (!initerr) { |
455 | initstk->i_brace = 1; | | 468 | initstk->i_brace = 1; |
456 | DPRINTF(("%s: %p %s\n", __func__, | | 469 | DPRINTF(("%s: %p %s\n", __func__, |
457 | namedmem, | | 470 | namedmem, |
458 | tyname(buf, sizeof(buf), | | 471 | tyname(buf, sizeof(buf), |
459 | initstk->i_type ? initstk->i_type : initstk->i_subt))); | | 472 | initstk->i_type ? initstk->i_type : initstk->i_subt))); |
460 | } | | 473 | } |
461 | } | | 474 | } |
462 | | | 475 | |
463 | static void | | 476 | static void |
464 | initstack_next_nobrace(void) | | 477 | initstack_next_nobrace(void) |
465 | { | | 478 | { |
466 | | | 479 | |
467 | DPRINTF(("%s\n", __func__)); | | 480 | DPRINTF(("%s\n", __func__)); |
468 | if (initstk->i_type == NULL && | | 481 | if (initstk->i_type == NULL && |
469 | !tspec_is_scalar(initstk->i_subt->t_tspec)) { | | 482 | !tspec_is_scalar(initstk->i_subt->t_tspec)) { |
470 | /* {}-enclosed initializer required */ | | 483 | /* {}-enclosed initializer required */ |
471 | error(181); | | 484 | error(181); |
472 | } | | 485 | } |
473 | | | 486 | |
474 | /* Make sure an entry with a scalar type is at the top of the stack. */ | | 487 | /* Make sure an entry with a scalar type is at the top of the stack. */ |
475 | if (!initerr) | | 488 | if (!initerr) |
476 | initstack_check_too_many(); | | 489 | initstack_check_too_many(); |
477 | while (!initerr) { | | 490 | while (!initerr) { |
478 | if ((initstk->i_type != NULL && | | 491 | if ((initstk->i_type != NULL && |
479 | tspec_is_scalar(initstk->i_type->t_tspec))) | | 492 | tspec_is_scalar(initstk->i_type->t_tspec))) |
480 | break; | | 493 | break; |
481 | initstack_push(); | | 494 | initstack_push(); |
482 | } | | 495 | } |
483 | } | | 496 | } |
484 | | | 497 | |
485 | void | | 498 | void |
486 | init_lbrace(void) | | 499 | init_lbrace(void) |
487 | { | | 500 | { |
488 | DPRINTF(("%s\n", __func__)); | | 501 | DPRINTF(("%s\n", __func__)); |
489 | | | 502 | |
490 | if (initerr) | | 503 | if (initerr) |
491 | return; | | 504 | return; |
492 | | | 505 | |
493 | if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && | | 506 | if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && |
494 | initstk->i_next == NULL) { | | 507 | initstk->i_next == NULL) { |
495 | if (tflag && !tspec_is_scalar(initstk->i_subt->t_tspec)) | | 508 | if (tflag && !tspec_is_scalar(initstk->i_subt->t_tspec)) |
496 | /* no automatic aggregate initialization in trad. C */ | | 509 | /* no automatic aggregate initialization in trad. C */ |
497 | warning(188); | | 510 | warning(188); |
498 | } | | 511 | } |
499 | | | 512 | |
500 | /* | | 513 | /* |
501 | * Remove all entries which cannot be used for further initializers | | 514 | * Remove all entries which cannot be used for further initializers |
502 | * and do not expect a closing brace. | | 515 | * and do not expect a closing brace. |
503 | */ | | 516 | */ |
504 | initstack_pop_nobrace(); | | 517 | initstack_pop_nobrace(); |
505 | | | 518 | |
506 | initstack_next_brace(); | | 519 | initstack_next_brace(); |
507 | } | | 520 | } |
508 | | | 521 | |
509 | void | | 522 | void |
510 | init_rbrace(void) | | 523 | init_rbrace(void) |
511 | { | | 524 | { |
512 | DPRINTF(("%s\n", __func__)); | | 525 | DPRINTF(("%s\n", __func__)); |
513 | | | 526 | |
514 | if (initerr) | | 527 | if (initerr) |
515 | return; | | 528 | return; |
516 | | | 529 | |
517 | initstack_pop_brace(); | | 530 | initstack_pop_brace(); |
518 | } | | 531 | } |
519 | | | 532 | |
520 | void | | 533 | void |
521 | mkinit(tnode_t *tn) | | 534 | mkinit(tnode_t *tn) |
522 | { | | 535 | { |
523 | ptrdiff_t offs; | | 536 | ptrdiff_t offs; |
524 | sym_t *sym; | | 537 | sym_t *sym; |
525 | tspec_t lt, rt; | | 538 | tspec_t lt, rt; |
526 | tnode_t *ln; | | 539 | tnode_t *ln; |
527 | struct mbl *tmem; | | 540 | struct mbl *tmem; |
528 | scl_t sc; | | 541 | scl_t sc; |
529 | #ifdef DEBUG | | 542 | #ifdef DEBUG |
530 | char buf[64], sbuf[64]; | | 543 | char buf[64], sbuf[64]; |
531 | #endif | | 544 | #endif |
532 | | | 545 | |
533 | DPRINTF(("%s: type=%s, value=%s\n", __func__, | | 546 | DPRINTF(("%s: type=%s, value=%s\n", __func__, |
534 | tyname(buf, sizeof(buf), tn->tn_type), | | 547 | tyname(buf, sizeof(buf), tn->tn_type), |
535 | print_tnode(sbuf, sizeof(sbuf), tn))); | | 548 | print_tnode(sbuf, sizeof(sbuf), tn))); |
536 | if (initerr || tn == NULL) | | 549 | if (initerr || tn == NULL) |
537 | return; | | 550 | return; |
538 | | | 551 | |
539 | sc = initsym->s_scl; | | 552 | sc = initsym->s_scl; |
540 | | | 553 | |
541 | /* | | 554 | /* |
542 | * Do not test for automatic aggregate initialisation. If the | | 555 | * Do not test for automatic aggregate initialisation. If the |
543 | * initializer starts with a brace we have the warning already. | | 556 | * initializer starts with a brace we have the warning already. |
544 | * If not, an error will be printed that the initializer must | | 557 | * If not, an error will be printed that the initializer must |
545 | * be enclosed by braces. | | 558 | * be enclosed by braces. |
546 | */ | | 559 | */ |
547 | | | 560 | |
548 | /* | | 561 | /* |
549 | * Local initialisation of non-array-types with only one expression | | 562 | * Local initialisation of non-array-types with only one expression |
550 | * without braces is done by ASSIGN | | 563 | * without braces is done by ASSIGN |
551 | */ | | 564 | */ |
552 | if ((sc == AUTO || sc == REG) && | | 565 | if ((sc == AUTO || sc == REG) && |
553 | initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) { | | 566 | initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) { |
554 | ln = getnnode(initsym, 0); | | 567 | ln = getnnode(initsym, 0); |
555 | ln->tn_type = tduptyp(ln->tn_type); | | 568 | ln->tn_type = tduptyp(ln->tn_type); |
556 | ln->tn_type->t_const = 0; | | 569 | ln->tn_type->t_const = 0; |
557 | tn = build(ASSIGN, ln, tn); | | 570 | tn = build(ASSIGN, ln, tn); |
558 | expr(tn, 0, 0, 0); | | 571 | expr(tn, 0, 0, 0); |
559 | return; | | 572 | return; |
560 | } | | 573 | } |
561 | | | 574 | |
562 | /* | | 575 | /* |
563 | * Remove all entries which cannot be used for further initializers | | 576 | * Remove all entries which cannot be used for further initializers |
564 | * and do not require a closing brace. | | 577 | * and do not require a closing brace. |
565 | */ | | 578 | */ |
566 | initstack_pop_nobrace(); | | 579 | initstack_pop_nobrace(); |
567 | | | 580 | |
568 | /* Initialisations by strings are done in initstack_string(). */ | | 581 | /* Initialisations by strings are done in initstack_string(). */ |
569 | if (initstack_string(tn)) | | 582 | if (initstack_string(tn)) |
570 | return; | | 583 | return; |
571 | | | 584 | |
572 | initstack_next_nobrace(); | | 585 | initstack_next_nobrace(); |
573 | if (initerr || tn == NULL) | | 586 | if (initerr || tn == NULL) |
574 | return; | | 587 | return; |
575 | | | 588 | |
576 | initstk->i_remaining--; | | 589 | initstk->i_remaining--; |
577 | DPRINTF(("%s: remaining=%d tn=%p\n", __func__, | | 590 | DPRINTF(("%s: remaining=%d tn=%p\n", __func__, |
578 | initstk->i_remaining, tn)); | | 591 | initstk->i_remaining, tn)); |
579 | /* Create a temporary node for the left side. */ | | 592 | /* Create a temporary node for the left side. */ |
580 | ln = tgetblk(sizeof (tnode_t)); | | 593 | ln = tgetblk(sizeof (tnode_t)); |
581 | ln->tn_op = NAME; | | 594 | ln->tn_op = NAME; |
582 | ln->tn_type = tduptyp(initstk->i_type); | | 595 | ln->tn_type = tduptyp(initstk->i_type); |
583 | ln->tn_type->t_const = 0; | | 596 | ln->tn_type->t_const = 0; |
584 | ln->tn_lvalue = 1; | | 597 | ln->tn_lvalue = 1; |
585 | ln->tn_sym = initsym; /* better than nothing */ | | 598 | ln->tn_sym = initsym; /* better than nothing */ |
586 | | | 599 | |
587 | tn = cconv(tn); | | 600 | tn = cconv(tn); |
588 | | | 601 | |
589 | lt = ln->tn_type->t_tspec; | | 602 | lt = ln->tn_type->t_tspec; |
590 | rt = tn->tn_type->t_tspec; | | 603 | rt = tn->tn_type->t_tspec; |
591 | | | 604 | |
592 | lint_assert(tspec_is_scalar(lt)); | | 605 | lint_assert(tspec_is_scalar(lt)); |
593 | | | 606 | |
594 | if (!typeok(INIT, 0, ln, tn)) | | 607 | if (!typeok(INIT, 0, ln, tn)) |
595 | return; | | 608 | return; |
596 | | | 609 | |
597 | /* | | 610 | /* |
598 | * Store the tree memory. This is necessary because otherwise | | 611 | * Store the tree memory. This is necessary because otherwise |
599 | * expr() would free it. | | 612 | * expr() would free it. |
600 | */ | | 613 | */ |
601 | tmem = tsave(); | | 614 | tmem = tsave(); |
602 | expr(tn, 1, 0, 1); | | 615 | expr(tn, 1, 0, 1); |
603 | trestor(tmem); | | 616 | trestor(tmem); |
604 | | | 617 | |
605 | if (tspec_is_int(lt) && ln->tn_type->t_isfield && !tspec_is_int(rt)) { | | 618 | if (tspec_is_int(lt) && ln->tn_type->t_isfield && !tspec_is_int(rt)) { |
606 | /* | | 619 | /* |
607 | * Bit-fields can be initialized in trad. C only by integer | | 620 | * Bit-fields can be initialized in trad. C only by integer |
608 | * constants. | | 621 | * constants. |
609 | */ | | 622 | */ |
610 | if (tflag) | | 623 | if (tflag) |
611 | /* bit-field initialisation is illegal in trad. C */ | | 624 | /* bit-field initialisation is illegal in trad. C */ |
612 | warning(186); | | 625 | warning(186); |
613 | } | | 626 | } |
614 | | | 627 | |
615 | if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON)) | | 628 | if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON)) |
616 | tn = convert(INIT, 0, initstk->i_type, tn); | | 629 | tn = convert(INIT, 0, initstk->i_type, tn); |
617 | | | 630 | |
618 | if (tn != NULL && tn->tn_op != CON) { | | 631 | if (tn != NULL && tn->tn_op != CON) { |
619 | sym = NULL; | | 632 | sym = NULL; |
620 | offs = 0; | | 633 | offs = 0; |
621 | if (conaddr(tn, &sym, &offs) == -1) { | | 634 | if (conaddr(tn, &sym, &offs) == -1) { |
622 | if (sc == AUTO || sc == REG) { | | 635 | if (sc == AUTO || sc == REG) { |
623 | /* non-constant initializer */ | | 636 | /* non-constant initializer */ |
624 | (void)c99ism(177); | | 637 | (void)c99ism(177); |
625 | } else { | | 638 | } else { |
626 | /* non-constant initializer */ | | 639 | /* non-constant initializer */ |
627 | error(177); | | 640 | error(177); |
628 | } | | 641 | } |
629 | } | | 642 | } |
630 | } | | 643 | } |
631 | } | | 644 | } |
632 | | | 645 | |
633 | | | 646 | |
634 | static int | | 647 | static int |
635 | initstack_string(tnode_t *tn) | | 648 | initstack_string(tnode_t *tn) |
636 | { | | 649 | { |
637 | tspec_t t; | | 650 | tspec_t t; |
638 | istk_t *istk; | | 651 | istk_t *istk; |
639 | int len; | | 652 | int len; |
640 | strg_t *strg; | | 653 | strg_t *strg; |
641 | | | 654 | |
642 | if (tn->tn_op != STRING) | | 655 | if (tn->tn_op != STRING) |
643 | return 0; | | 656 | return 0; |
644 | | | 657 | |
645 | istk = initstk; | | 658 | istk = initstk; |
646 | strg = tn->tn_string; | | 659 | strg = tn->tn_string; |
647 | | | 660 | |
648 | /* | | 661 | /* |
649 | * Check if we have an array type which can be initialized by | | 662 | * Check if we have an array type which can be initialized by |
650 | * the string. | | 663 | * the string. |
651 | */ | | 664 | */ |
652 | if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) { | | 665 | if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) { |
653 | DPRINTF(("%s: subt array\n", __func__)); | | 666 | DPRINTF(("%s: subt array\n", __func__)); |
654 | t = istk->i_subt->t_subt->t_tspec; | | 667 | t = istk->i_subt->t_subt->t_tspec; |
655 | if (!((strg->st_tspec == CHAR && | | 668 | if (!((strg->st_tspec == CHAR && |
656 | (t == CHAR || t == UCHAR || t == SCHAR)) || | | 669 | (t == CHAR || t == UCHAR || t == SCHAR)) || |
657 | (strg->st_tspec == WCHAR && t == WCHAR))) { | | 670 | (strg->st_tspec == WCHAR && t == WCHAR))) { |
658 | return 0; | | 671 | return 0; |
659 | } | | 672 | } |
660 | /* Put the array at top of stack */ | | 673 | /* Put the array at top of stack */ |
661 | initstack_push(); | | 674 | initstack_push(); |
662 | istk = initstk; | | 675 | istk = initstk; |
663 | } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) { | | 676 | } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) { |
664 | DPRINTF(("%s: type array\n", __func__)); | | 677 | DPRINTF(("%s: type array\n", __func__)); |
665 | t = istk->i_type->t_subt->t_tspec; | | 678 | t = istk->i_type->t_subt->t_tspec; |
666 | if (!((strg->st_tspec == CHAR && | | 679 | if (!((strg->st_tspec == CHAR && |
667 | (t == CHAR || t == UCHAR || t == SCHAR)) || | | 680 | (t == CHAR || t == UCHAR || t == SCHAR)) || |
668 | (strg->st_tspec == WCHAR && t == WCHAR))) { | | 681 | (strg->st_tspec == WCHAR && t == WCHAR))) { |
669 | return 0; | | 682 | return 0; |
670 | } | | 683 | } |
671 | /* | | 684 | /* |
672 | * If the array is already partly initialized, we are | | 685 | * If the array is already partly initialized, we are |
673 | * wrong here. | | 686 | * wrong here. |
674 | */ | | 687 | */ |
675 | if (istk->i_remaining != istk->i_type->t_dim) | | 688 | if (istk->i_remaining != istk->i_type->t_dim) |
676 | return 0; | | 689 | return 0; |
677 | } else { | | 690 | } else { |
678 | return 0; | | 691 | return 0; |
679 | } | | 692 | } |
680 | | | 693 | |
681 | /* Get length without trailing NUL character. */ | | 694 | /* Get length without trailing NUL character. */ |
682 | len = strg->st_len; | | 695 | len = strg->st_len; |
683 | | | 696 | |
684 | if (istk->i_nolimit) { | | 697 | if (istk->i_nolimit) { |
685 | istk->i_nolimit = 0; | | 698 | istk->i_nolimit = 0; |
686 | istk->i_type->t_dim = len + 1; | | 699 | istk->i_type->t_dim = len + 1; |
687 | setcomplete(istk->i_type, 1); | | 700 | setcomplete(istk->i_type, 1); |
688 | } else { | | 701 | } else { |
689 | if (istk->i_type->t_dim < len) { | | 702 | if (istk->i_type->t_dim < len) { |
690 | /* non-null byte ignored in string initializer */ | | 703 | /* non-null byte ignored in string initializer */ |
691 | warning(187); | | 704 | warning(187); |
692 | } | | 705 | } |
693 | } | | 706 | } |
694 | | | 707 | |
695 | /* In every case the array is initialized completely. */ | | 708 | /* In every case the array is initialized completely. */ |
696 | istk->i_remaining = 0; | | 709 | istk->i_remaining = 0; |
697 | | | 710 | |
698 | return 1; | | 711 | return 1; |
699 | } | | 712 | } |