| @@ -1,17 +1,18 @@ | | | @@ -1,17 +1,18 @@ |
1 | /* $NetBSD: init.c,v 1.178 2021/03/29 21:34:17 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.179 2021/03/30 14:25:28 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 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
6 | * | | 7 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 10 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
15 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
16 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
17 | * This product includes software developed by Jochen Pohl for | | 18 | * This product includes software developed by Jochen Pohl for |
| @@ -27,323 +28,213 @@ | | | @@ -27,323 +28,213 @@ |
27 | * 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, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (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 |
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 33 | */ |
33 | | | 34 | |
34 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
35 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
36 | #endif | | 37 | #endif |
37 | | | 38 | |
38 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
39 | #if defined(__RCSID) && !defined(lint) | | 40 | #if defined(__RCSID) && !defined(lint) |
40 | __RCSID("$NetBSD: init.c,v 1.178 2021/03/29 21:34:17 rillig Exp $"); | | 41 | __RCSID("$NetBSD: init.c,v 1.179 2021/03/30 14:25:28 rillig Exp $"); |
41 | #endif | | 42 | #endif |
42 | | | 43 | |
43 | #include <stdlib.h> | | 44 | #include <stdlib.h> |
44 | #include <string.h> | | 45 | #include <string.h> |
45 | | | 46 | |
46 | #include "lint1.h" | | 47 | #include "lint1.h" |
47 | | | 48 | |
48 | | | 49 | |
49 | /* | | 50 | /* |
50 | * Initialization | | 51 | * Initialization of global or local objects, like in: |
51 | * | | | |
52 | * Handles initializations of global or local objects, like in: | | | |
53 | * | | 52 | * |
54 | * int number = 12345; | | 53 | * int number = 12345; |
55 | * int number_with_braces = { 12345 }; | | 54 | * int number_with_braces = { 12345 }; |
56 | * | | 55 | * |
57 | * int array_of_unknown_size[] = { 111, 222, 333 }; | | 56 | * int array_of_unknown_size[] = { 111, 222, 333 }; |
58 | * int array_flat[2][2] = { 11, 12, 21, 22 }; | | 57 | * int array_flat[2][2] = { 11, 12, 21, 22 }; |
59 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; | | 58 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; |
60 | * | | 59 | * |
61 | * struct { int x, y; } point = { 3, 4 }; | | 60 | * struct { int x, y; } point = { 3, 4 }; |
62 | * struct { int x, y; } point = { .y = 4, .x = 3 }; | | 61 | * struct { int x, y; } point = { .y = 4, .x = 3 }; |
63 | * | | 62 | * |
64 | * Any scalar expression in the initializer may be surrounded by arbitrarily | | 63 | * Any scalar expression in the initializer may be surrounded by arbitrarily |
65 | * many extra pairs of braces, like in the example 'number_with_braces' (C99 | | 64 | * many extra pairs of braces, like in the example 'number_with_braces' (C99 |
66 | * 6.7.8p11). | | 65 | * 6.7.8p11). |
67 | * | | 66 | * |
68 | * For multi-dimensional arrays, the inner braces may be omitted like in | | 67 | * For multi-dimensional arrays, the inner braces may be omitted like in |
69 | * array_flat or spelled out like in array_nested. | | 68 | * array_flat or spelled out like in array_nested. This is unusual in |
| | | 69 | * practice and therefore only supported very basically. |
70 | * | | 70 | * |
71 | * For the initializer, the grammar parser calls these functions: | | 71 | * During initialization, the grammar parser calls these functions: |
72 | * | | 72 | * |
73 | * begin_initialization | | 73 | * begin_initialization |
74 | * init_lbrace for each '{' | | 74 | * init_lbrace for each '{' |
75 | * add_designator_member for each '.member' before '=' | | 75 | * add_designator_member for each '.member' before '=' |
76 | * add_designator_subscript for each '[123]' before '=' | | 76 | * add_designator_subscript for each '[123]' before '=' |
77 | * init_using_expr for each expression | | 77 | * init_expr for each expression |
78 | * init_rbrace for each '}' | | 78 | * init_rbrace for each '}' |
79 | * end_initialization | | 79 | * end_initialization |
80 | * | | 80 | * |
81 | * Each '{' begins a new brace level, each '}' ends the current brace level. | | 81 | * Each '{' begins a new brace level, each '}' ends the current brace level. |
82 | * Each brace level has an associated "current object". | | 82 | * Each brace level has an associated "current object". |
83 | * | | 83 | * |
84 | * Most of the time, the topmost level of brace_level contains a scalar type, | | | |
85 | * and its remaining count toggles between 1 and 0. | | | |
86 | * | | | |
87 | * See also: | | 84 | * See also: |
88 | * C99 6.7.8 "Initialization" | | 85 | * C99 6.7.8 "Initialization" |
89 | * d_c99_init.c for more examples | | 86 | * d_c99_init.c for more examples |
90 | */ | | 87 | */ |
91 | | | 88 | |
92 | | | | |
93 | /* | | | |
94 | * Describes a single brace level of an ongoing initialization. | | | |
95 | * | | | |
96 | * XXX: Since C99, the initializers can be listed in arbitrary order by using | | | |
97 | * designators to specify the sub-object to be initialized. The member names | | | |
98 | * of non-leaf structs may thus appear repeatedly, as demonstrated in | | | |
99 | * d_init_pop_member.c. | | | |
100 | * | | | |
101 | * See C99 6.7.8, which spans 6 pages full of tricky details and carefully | | | |
102 | * selected examples. | | | |
103 | */ | | | |
104 | struct brace_level { | | | |
105 | | | | |
106 | /* | | | |
107 | * The type of the current object that is initialized at this brace | | | |
108 | * level. | | | |
109 | * | | | |
110 | * On the outermost element, this is always NULL since the outermost | | | |
111 | * initializer-expression may be enclosed in an optional pair of | | | |
112 | * braces, as of the current implementation. | | | |
113 | * | | | |
114 | * FIXME: This approach is wrong. It's not that the outermost | | | |
115 | * initializer may be enclosed in additional braces, it's every scalar | | | |
116 | * that may be enclosed in additional braces, as of C99 6.7.8p11. | | | |
117 | * | | | |
118 | * Everywhere else it is nonnull. | | | |
119 | */ | | | |
120 | type_t *bl_type; | | | |
121 | | | | |
122 | /* | | | |
123 | * The type that will be initialized at the next initialization level, | | | |
124 | * usually enclosed by another pair of braces. | | | |
125 | * | | | |
126 | * For an array, it is the element type, but without 'const'. | | | |
127 | * | | | |
128 | * For a struct or union type, it is one of the member types, but | | | |
129 | * without 'const'. | | | |
130 | * | | | |
131 | * The outermost stack element has no bl_type but nevertheless has | | | |
132 | * bl_subtype. For example, in 'int var = { 12345 }', initially there | | | |
133 | * is a brace_level with bl_subtype 'int'. When the '{' is processed, | | | |
134 | * an element with bl_type 'int' is pushed to the stack. When the | | | |
135 | * corresponding '}' is processed, the inner element is popped again. | | | |
136 | * | | | |
137 | * During initialization, only the top 2 elements of the stack are | | | |
138 | * looked at. | | | |
139 | * | | | |
140 | * XXX: Having bl_subtype here is the wrong approach, it should not be | | | |
141 | * necessary at all; see bl_type. | | | |
142 | */ | | | |
143 | type_t *bl_subtype; | | | |
144 | | | | |
145 | /* | | | |
146 | * Whether this level of the initializer requires a '}' to be | | | |
147 | * completed. | | | |
148 | * | | | |
149 | * Multidimensional arrays do not need a closing brace to complete | | | |
150 | * an inner array; for example, { 1, 2, 3, 4 } is a valid initializer | | | |
151 | * for 'int arr[2][2]'. | | | |
152 | * | | | |
153 | * XXX: Double-check whether this is the correct approach at all; see | | | |
154 | * bl_type. | | | |
155 | */ | | | |
156 | bool bl_brace: 1; | | | |
157 | | | | |
158 | /* Whether bl_type is an array of unknown size. */ | | | |
159 | bool bl_array_of_unknown_size: 1; | | | |
160 | | | | |
161 | /* | | | |
162 | * XXX: This feels wrong. Whether or not there has been a named | | | |
163 | * initializer (called 'designation' since C99) should not matter at | | | |
164 | * all. Even after an initializer with designation, counting of the | | | |
165 | * remaining elements continues, see C99 6.7.8p17. | | | |
166 | */ | | | |
167 | bool bl_seen_named_member: 1; | | | |
168 | | | | |
169 | /* | | | |
170 | * For structs, the next member to be initialized by a designator-less | | | |
171 | * initializer. | | | |
172 | */ | | | |
173 | sym_t *bl_next_member; | | | |
174 | | | | |
175 | /* TODO: Add bl_next_subscript for arrays. */ | | | |
176 | | | | |
177 | /* TODO: Understand C99 6.7.8p17 and footnote 128 for unions. */ | | | |
178 | | | | |
179 | /* | | | |
180 | * The number of remaining elements to be used by expressions without | | | |
181 | * designator. | | | |
182 | * | | | |
183 | * This says nothing about which members have been initialized or not | | | |
184 | * since starting with C99, members may be initialized in arbitrary | | | |
185 | * order by using designators. | | | |
186 | * | | | |
187 | * For an array of unknown size, this is always 0 and thus irrelevant. | | | |
188 | * | | | |
189 | * XXX: for scalars? | | | |
190 | * XXX: for structs? | | | |
191 | * XXX: for unions? | | | |
192 | * XXX: for arrays? | | | |
193 | * | | | |
194 | * XXX: Having the count of remaining objects should not be necessary. | | | |
195 | * It is probably clearer to use bl_next_member and bl_next_subscript | | | |
196 | * for this purpose. | | | |
197 | */ | | | |
198 | int bl_remaining; | | | |
199 | | | | |
200 | /* | | | |
201 | * The initialization state of the enclosing data structure | | | |
202 | * (struct, union, array). | | | |
203 | * | | | |
204 | * XXX: Or for a scalar, for the top-level element, or for expressions | | | |
205 | * in redundant braces such as '{{{{ 0 }}}}' (not yet implemented as | | | |
206 | * of 2021-03-25). | | | |
207 | */ | | | |
208 | struct brace_level *bl_enclosing; | | | |
209 | }; | | | |
210 | | | | |
211 | /* | | 89 | /* |
212 | * A single component on the path to the sub-object that is initialized by an | | 90 | * A single component on the path to the sub-object that is initialized by an |
213 | * initializer expression. Either a struct or union member, or an array | | 91 | * initializer expression. Either a struct or union member, or an array |
214 | * subscript. | | 92 | * subscript. |
215 | * | | 93 | * |
216 | * See also: C99 6.7.8 "Initialization" | | 94 | * C99 6.7.8p6, 6.7.8p7 |
217 | */ | | 95 | */ |
218 | struct designator { | | 96 | struct designator { |
219 | const char *dr_name; /* for struct and union */ | | 97 | const char *dr_name; /* for struct and union */ |
220 | /* TODO: add 'dr_subscript' for arrays */ | | 98 | size_t dr_subscript; /* for array */ |
221 | struct designator *dr_next; | | 99 | struct designator *dr_next; |
222 | }; | | 100 | }; |
223 | | | 101 | |
224 | /* | | 102 | /* |
225 | * The optional designation for an initializer, saying which sub-object to | | 103 | * The optional designation for an initializer, saying which sub-object to |
226 | * initialize. Examples for designations are '.member' or | | 104 | * initialize. Examples for designations are '.member' or |
227 | * '.member[123].member.member[1][1]'. | | 105 | * '.member[123].member.member[1][1]'. |
228 | * | | 106 | * |
229 | * See also: C99 6.7.8 "Initialization" | | 107 | * C99 6.7.8p6, 6.7.8p7 |
230 | */ | | 108 | */ |
231 | struct designation { | | 109 | struct designation { |
232 | struct designator *dn_head; | | 110 | struct designator *dn_head; |
233 | struct designator *dn_tail; | | 111 | struct designator *dn_tail; |
234 | }; | | 112 | }; |
235 | | | 113 | |
| | | 114 | /* |
| | | 115 | * Describes a single brace level of an ongoing initialization. |
| | | 116 | * |
| | | 117 | * See C99 6.7.8p17. |
| | | 118 | */ |
| | | 119 | struct brace_level { |
| | | 120 | /* |
| | | 121 | * The type of the current object that is initialized at this brace |
| | | 122 | * level. |
| | | 123 | */ |
| | | 124 | const type_t *bl_type; |
| | | 125 | const sym_t *bl_next_member; /* for structs and unions */ |
| | | 126 | size_t bl_array_next_subscript; |
| | | 127 | bool bl_array_of_unknown_size: 1; |
| | | 128 | bool bl_scalar_done: 1; /* for scalars */ |
| | | 129 | bool bl_omitted_braces: 1; /* skip further checks */ |
| | | 130 | struct designation bl_designation; /* .member[123].member */ |
| | | 131 | struct brace_level *bl_enclosing; |
| | | 132 | }; |
| | | 133 | |
236 | struct initialization { | | 134 | struct initialization { |
237 | /* | | 135 | /* |
238 | * is set as soon as a fatal error occurred in the initialization. | | 136 | * Is set as soon as a fatal error occurred in the initialization. |
239 | * The effect is that the rest of the initialization is ignored | | 137 | * The effect is that the rest of the initialization is ignored |
240 | * (parsed by yacc, expression trees built, but no initialization | | 138 | * (parsed by yacc, expression trees built, but no initialization |
241 | * takes place). | | 139 | * takes place). |
242 | */ | | 140 | */ |
243 | bool in_err; | | 141 | bool in_err; |
244 | | | 142 | |
245 | /* The symbol that is to be initialized. */ | | 143 | /* The symbol that is to be initialized. */ |
246 | sym_t *in_sym; | | 144 | sym_t *in_sym; |
247 | | | 145 | |
248 | /* The innermost brace level. */ | | 146 | /* The innermost brace level. */ |
249 | struct brace_level *in_brace_level; | | 147 | struct brace_level *in_brace_level; |
250 | | | 148 | |
251 | /* | | 149 | struct initialization *in_enclosing; |
252 | * The C99 designator, if any, for the current initialization | | | |
253 | * expression. | | | |
254 | */ | | | |
255 | struct designation in_designation; | | | |
256 | | | | |
257 | struct initialization *in_next; | | | |
258 | }; | | 150 | }; |
259 | | | 151 | |
260 | | | 152 | |
261 | static struct initialization *init; | | | |
262 | | | | |
263 | | | | |
264 | #ifdef DEBUG | | 153 | #ifdef DEBUG |
265 | static int debug_ind = 0; | | 154 | static int debug_indentation = 0; |
266 | #endif | | 155 | #endif |
267 | | | 156 | |
268 | | | 157 | |
269 | #ifdef DEBUG | | 158 | #ifdef DEBUG |
270 | | | 159 | |
271 | static void __printflike(1, 2) | | 160 | static void __printflike(1, 2) |
272 | debug_printf(const char *fmt, ...) | | 161 | debug_printf(const char *fmt, ...) |
273 | { | | 162 | { |
274 | va_list va; | | 163 | va_list va; |
275 | | | 164 | |
276 | va_start(va, fmt); | | 165 | va_start(va, fmt); |
277 | vfprintf(stdout, fmt, va); | | 166 | vfprintf(stdout, fmt, va); |
278 | va_end(va); | | 167 | va_end(va); |
279 | } | | 168 | } |
280 | | | 169 | |
281 | static void | | 170 | static void |
282 | debug_indent(void) | | 171 | debug_indent(void) |
283 | { | | 172 | { |
284 | | | 173 | |
285 | debug_printf("%*s", 2 * debug_ind, ""); | | 174 | debug_printf("%*s", 2 * debug_indentation, ""); |
286 | } | | 175 | } |
287 | | | 176 | |
288 | static void | | 177 | static void |
289 | debug_enter(const char *func) | | 178 | debug_enter(const char *func) |
290 | { | | 179 | { |
291 | | | 180 | |
292 | printf("%*s+ %s\n", 2 * debug_ind++, "", func); | | 181 | printf("%*s+ %s\n", 2 * debug_indentation++, "", func); |
293 | } | | 182 | } |
294 | | | 183 | |
295 | static void __printflike(1, 2) | | 184 | static void __printflike(1, 2) |
296 | debug_step(const char *fmt, ...) | | 185 | debug_step(const char *fmt, ...) |
297 | { | | 186 | { |
298 | va_list va; | | 187 | va_list va; |
299 | | | 188 | |
300 | debug_indent(); | | 189 | debug_indent(); |
301 | va_start(va, fmt); | | 190 | va_start(va, fmt); |
302 | vfprintf(stdout, fmt, va); | | 191 | vfprintf(stdout, fmt, va); |
303 | va_end(va); | | 192 | va_end(va); |
304 | printf("\n"); | | 193 | printf("\n"); |
305 | } | | 194 | } |
306 | | | 195 | |
307 | static void | | 196 | static void |
308 | debug_leave(const char *func) | | 197 | debug_leave(const char *func) |
309 | { | | 198 | { |
310 | | | 199 | |
311 | printf("%*s- %s\n", 2 * --debug_ind, "", func); | | 200 | printf("%*s- %s\n", 2 * --debug_indentation, "", func); |
312 | } | | 201 | } |
313 | | | 202 | |
314 | #define debug_enter() (debug_enter)(__func__) | | 203 | #define debug_enter() (debug_enter)(__func__) |
315 | #define debug_leave() (debug_leave)(__func__) | | 204 | #define debug_leave() (debug_leave)(__func__) |
316 | | | 205 | |
317 | #else | | 206 | #else |
318 | | | 207 | |
| | | 208 | /* TODO: This is C99 */ |
319 | #define debug_printf(fmt, ...) do { } while (false) | | 209 | #define debug_printf(fmt, ...) do { } while (false) |
320 | #define debug_indent() do { } while (false) | | 210 | #define debug_indent() do { } while (false) |
321 | #define debug_enter() do { } while (false) | | 211 | #define debug_enter() do { } while (false) |
322 | #define debug_step(fmt, ...) do { } while (false) | | 212 | #define debug_step(fmt, ...) do { } while (false) |
323 | #define debug_leave() do { } while (false) | | 213 | #define debug_leave() do { } while (false) |
324 | | | 214 | |
325 | #endif | | 215 | #endif |
326 | | | 216 | |
327 | | | 217 | |
328 | static void * | | 218 | static void * |
329 | unconst_cast(const void *p) | | 219 | unconst_cast(const void *p) |
330 | { | | 220 | { |
331 | void *r; | | 221 | void *r; |
332 | | | 222 | |
333 | memcpy(&r, &p, sizeof r); | | 223 | memcpy(&r, &p, sizeof r); |
334 | return r; | | 224 | return r; |
335 | } | | 225 | } |
336 | | | 226 | |
| | | 227 | /* C99 6.7.8p7 */ |
337 | static bool | | 228 | static bool |
338 | is_struct_or_union(tspec_t t) | | 229 | is_struct_or_union(tspec_t t) |
339 | { | | 230 | { |
340 | | | 231 | |
341 | return t == STRUCT || t == UNION; | | 232 | return t == STRUCT || t == UNION; |
342 | } | | 233 | } |
343 | | | 234 | |
344 | static bool | | 235 | static bool |
345 | has_automatic_storage_duration(const sym_t *sym) | | 236 | has_automatic_storage_duration(const sym_t *sym) |
346 | { | | 237 | { |
347 | | | 238 | |
348 | return sym->s_scl == AUTO || sym->s_scl == REG; | | 239 | return sym->s_scl == AUTO || sym->s_scl == REG; |
349 | } | | 240 | } |
| @@ -355,42 +246,95 @@ is_string_array(const type_t *tp, tspec_ | | | @@ -355,42 +246,95 @@ is_string_array(const type_t *tp, tspec_ |
355 | tspec_t st; | | 246 | tspec_t st; |
356 | | | 247 | |
357 | if (tp == NULL || tp->t_tspec != ARRAY) | | 248 | if (tp == NULL || tp->t_tspec != ARRAY) |
358 | return false; | | 249 | return false; |
359 | | | 250 | |
360 | st = tp->t_subt->t_tspec; | | 251 | st = tp->t_subt->t_tspec; |
361 | return t == CHAR | | 252 | return t == CHAR |
362 | ? st == CHAR || st == UCHAR || st == SCHAR | | 253 | ? st == CHAR || st == UCHAR || st == SCHAR |
363 | : st == WCHAR; | | 254 | : st == WCHAR; |
364 | } | | 255 | } |
365 | | | 256 | |
366 | /* C99 6.7.8p9 */ | | 257 | /* C99 6.7.8p9 */ |
367 | static bool | | 258 | static bool |
368 | is_unnamed_member(const sym_t *m) | | 259 | is_unnamed(const sym_t *m) |
369 | { | | 260 | { |
370 | | | 261 | |
371 | return m->s_bitfield && m->s_name == unnamed; | | 262 | return m->s_bitfield && m->s_name == unnamed; |
372 | } | | 263 | } |
373 | | | 264 | |
| | | 265 | /* C99 6.7.8p9 */ |
| | | 266 | static const sym_t * |
| | | 267 | skip_unnamed(const sym_t *m) |
| | | 268 | { |
| | | 269 | |
| | | 270 | while (m != NULL && is_unnamed(m)) |
| | | 271 | m = m->s_next; |
| | | 272 | return m; |
| | | 273 | } |
| | | 274 | |
374 | static const sym_t * | | 275 | static const sym_t * |
375 | look_up_member(const sym_t *m, const char *name) | | 276 | first_named_member(const type_t *tp) |
376 | { | | 277 | { |
377 | | | 278 | |
378 | for (; m != NULL; m = m->s_next) | | 279 | lint_assert(is_struct_or_union(tp->t_tspec)); |
379 | if (!is_unnamed_member(m) && strcmp(m->s_name, name) == 0) | | 280 | return skip_unnamed(tp->t_str->sou_first_member); |
| | | 281 | } |
| | | 282 | |
| | | 283 | static const sym_t * |
| | | 284 | look_up_member(const type_t *tp, const char *name) |
| | | 285 | { |
| | | 286 | const sym_t *m; |
| | | 287 | |
| | | 288 | lint_assert(is_struct_or_union(tp->t_tspec)); |
| | | 289 | for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) |
| | | 290 | if (!is_unnamed(m) && strcmp(m->s_name, name) == 0) |
380 | return m; | | 291 | return m; |
381 | return NULL; | | 292 | return NULL; |
382 | } | | 293 | } |
383 | | | 294 | |
| | | 295 | static const type_t * |
| | | 296 | sym_type(const sym_t *sym) |
| | | 297 | { |
| | | 298 | |
| | | 299 | return sym != NULL ? sym->s_type : NULL; |
| | | 300 | } |
| | | 301 | |
| | | 302 | static const type_t * |
| | | 303 | look_up_member_type(const type_t *tp, const char *name) |
| | | 304 | { |
| | | 305 | const sym_t *member; |
| | | 306 | |
| | | 307 | member = look_up_member(tp, name); |
| | | 308 | if (member == NULL) { |
| | | 309 | /* TODO: add type information */ |
| | | 310 | /* undefined struct/union member: %s */ |
| | | 311 | error(101, name); |
| | | 312 | } |
| | | 313 | |
| | | 314 | return sym_type(member); |
| | | 315 | } |
| | | 316 | |
| | | 317 | static void |
| | | 318 | update_type_of_array_of_unknown_size(sym_t *sym, size_t size) |
| | | 319 | { |
| | | 320 | type_t *tp; |
| | | 321 | |
| | | 322 | tp = duptyp(sym->s_type); |
| | | 323 | tp->t_dim = (int)size; |
| | | 324 | tp->t_incomplete_array = false; |
| | | 325 | sym->s_type = tp; |
| | | 326 | } |
| | | 327 | |
384 | | | 328 | |
385 | /* In traditional C, bit-fields can be initialized only by integer constants. */ | | 329 | /* In traditional C, bit-fields can be initialized only by integer constants. */ |
386 | static void | | 330 | static void |
387 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) | | 331 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) |
388 | { | | 332 | { |
389 | | | 333 | |
390 | if (tflag && | | 334 | if (tflag && |
391 | is_integer(lt) && | | 335 | is_integer(lt) && |
392 | ln->tn_type->t_bitfield && | | 336 | ln->tn_type->t_bitfield && |
393 | !is_integer(rt)) { | | 337 | !is_integer(rt)) { |
394 | /* bit-field initialization is illegal in traditional C */ | | 338 | /* bit-field initialization is illegal in traditional C */ |
395 | warning(186); | | 339 | warning(186); |
396 | } | | 340 | } |
| @@ -408,26 +352,38 @@ check_non_constant_initializer(const tno | | | @@ -408,26 +352,38 @@ check_non_constant_initializer(const tno |
408 | if (constant_addr(tn, &unused_sym, &unused_offs)) | | 352 | if (constant_addr(tn, &unused_sym, &unused_offs)) |
409 | return; | | 353 | return; |
410 | | | 354 | |
411 | if (has_automatic_storage_duration(sym)) { | | 355 | if (has_automatic_storage_duration(sym)) { |
412 | /* non-constant initializer */ | | 356 | /* non-constant initializer */ |
413 | c99ism(177); | | 357 | c99ism(177); |
414 | } else { | | 358 | } else { |
415 | /* non-constant initializer */ | | 359 | /* non-constant initializer */ |
416 | error(177); | | 360 | error(177); |
417 | } | | 361 | } |
418 | } | | 362 | } |
419 | | | 363 | |
420 | static void | | 364 | static void |
| | | 365 | check_no_auto_aggregate(const sym_t *sym) |
| | | 366 | { |
| | | 367 | |
| | | 368 | if (tflag && |
| | | 369 | has_automatic_storage_duration(sym) && |
| | | 370 | !is_scalar(sym->s_type->t_tspec)) { |
| | | 371 | /* no automatic aggregate initialization in trad. C */ |
| | | 372 | warning(188); |
| | | 373 | } |
| | | 374 | } |
| | | 375 | |
| | | 376 | static void |
421 | check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn) | | 377 | check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn) |
422 | { | | 378 | { |
423 | tnode_t *ln; | | 379 | tnode_t *ln; |
424 | tspec_t lt, rt; | | 380 | tspec_t lt, rt; |
425 | struct mbl *tmem; | | 381 | struct mbl *tmem; |
426 | | | 382 | |
427 | /* Create a temporary node for the left side. */ | | 383 | /* Create a temporary node for the left side. */ |
428 | ln = tgetblk(sizeof *ln); | | 384 | ln = tgetblk(sizeof *ln); |
429 | ln->tn_op = NAME; | | 385 | ln->tn_op = NAME; |
430 | ln->tn_type = tduptyp(tp); | | 386 | ln->tn_type = tduptyp(tp); |
431 | ln->tn_type->t_const = false; | | 387 | ln->tn_type->t_const = false; |
432 | ln->tn_lvalue = true; | | 388 | ln->tn_lvalue = true; |
433 | ln->tn_sym = sym; | | 389 | ln->tn_sym = sym; |
| @@ -453,1042 +409,682 @@ check_init_expr(const type_t *tp, sym_t | | | @@ -453,1042 +409,682 @@ check_init_expr(const type_t *tp, sym_t |
453 | check_bit_field_init(ln, lt, rt); | | 409 | check_bit_field_init(ln, lt, rt); |
454 | | | 410 | |
455 | /* | | 411 | /* |
456 | * XXX: Is it correct to do this conversion _after_ the typeok above? | | 412 | * XXX: Is it correct to do this conversion _after_ the typeok above? |
457 | */ | | 413 | */ |
458 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) | | 414 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) |
459 | tn = convert(INIT, 0, unconst_cast(tp), tn); | | 415 | tn = convert(INIT, 0, unconst_cast(tp), tn); |
460 | | | 416 | |
461 | check_non_constant_initializer(tn, sym); | | 417 | check_non_constant_initializer(tn, sym); |
462 | } | | 418 | } |
463 | | | 419 | |
464 | | | 420 | |
465 | static struct designator * | | 421 | static struct designator * |
466 | designator_new(const char *name) | | 422 | designator_new(const char *name, size_t subscript) |
467 | { | | 423 | { |
468 | struct designator *dr; | | 424 | struct designator *dr; |
469 | | | 425 | |
470 | dr = xcalloc(1, sizeof *dr); | | 426 | dr = xcalloc(1, sizeof *dr); |
471 | dr->dr_name = name; | | 427 | dr->dr_name = name; |
| | | 428 | dr->dr_subscript = subscript; |
472 | return dr; | | 429 | return dr; |
473 | } | | 430 | } |
474 | | | 431 | |
475 | static void | | 432 | static void |
476 | designator_free(struct designator *dr) | | 433 | designator_free(struct designator *dr) |
477 | { | | 434 | { |
478 | | | 435 | |
479 | free(dr); | | 436 | free(dr); |
480 | } | | 437 | } |
481 | | | 438 | |
482 | | | 439 | |
| | | 440 | static const type_t * |
| | | 441 | designator_look_up(const struct designator *dr, const type_t *tp) |
| | | 442 | { |
| | | 443 | switch (tp->t_tspec) { |
| | | 444 | case STRUCT: |
| | | 445 | case UNION: |
| | | 446 | if (dr->dr_name == NULL) { |
| | | 447 | /* syntax error '%s' */ |
| | | 448 | error(249, "designator '[...]' is only for arrays"); |
| | | 449 | return sym_type(first_named_member(tp)); |
| | | 450 | } |
| | | 451 | |
| | | 452 | return look_up_member_type(tp, dr->dr_name); |
| | | 453 | case ARRAY: |
| | | 454 | if (dr->dr_name != NULL) { |
| | | 455 | /* TODO: reword; kept for compatibility */ |
| | | 456 | /* syntax error '%s' */ |
| | | 457 | error(249, |
| | | 458 | "named member must only be used with struct/union"); |
| | | 459 | } |
| | | 460 | return tp->t_subt; |
| | | 461 | default: |
| | | 462 | /* syntax error '%s' */ |
| | | 463 | error(249, "scalar type cannot use designator"); |
| | | 464 | return tp; |
| | | 465 | } |
| | | 466 | } |
| | | 467 | |
| | | 468 | |
483 | #ifdef DEBUG | | 469 | #ifdef DEBUG |
484 | static void | | 470 | static void |
485 | designation_debug(const struct designation *dn) | | 471 | designation_debug(const struct designation *dn) |
486 | { | | 472 | { |
487 | const struct designator *dr; | | 473 | const struct designator *dr; |
488 | | | 474 | |
489 | if (dn->dn_head == NULL) | | 475 | if (dn->dn_head == NULL) |
490 | return; | | 476 | return; |
491 | | | 477 | |
492 | debug_indent(); | | 478 | debug_indent(); |
493 | debug_printf("designation: "); | | 479 | debug_printf("designation: "); |
494 | for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) | | 480 | for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) { |
495 | debug_printf(".%s", dr->dr_name); | | 481 | if (dr->dr_name != NULL) { |
| | | 482 | debug_printf(".%s", dr->dr_name); |
| | | 483 | lint_assert(dr->dr_subscript == 0); |
| | | 484 | } else |
| | | 485 | debug_printf("[%zu]", dr->dr_subscript); |
| | | 486 | } |
496 | debug_printf("\n"); | | 487 | debug_printf("\n"); |
497 | } | | 488 | } |
498 | #else | | 489 | #else |
499 | #define designation_debug(dn) do { } while (false) | | 490 | #define designation_debug(dn) do { } while (false) |
500 | #endif | | 491 | #endif |
501 | | | 492 | |
502 | static void | | 493 | static void |
503 | designation_add(struct designation *dn, struct designator *dr) | | 494 | designation_add(struct designation *dn, const char *name, size_t subscript) |
504 | { | | 495 | { |
| | | 496 | struct designator *dr; |
| | | 497 | |
| | | 498 | dr = designator_new(name, subscript); |
505 | | | 499 | |
506 | if (dn->dn_head != NULL) { | | 500 | if (dn->dn_head != NULL) { |
507 | dn->dn_tail->dr_next = dr; | | 501 | dn->dn_tail->dr_next = dr; |
508 | dn->dn_tail = dr; | | 502 | dn->dn_tail = dr; |
509 | } else { | | 503 | } else { |
510 | dn->dn_head = dr; | | 504 | dn->dn_head = dr; |
511 | dn->dn_tail = dr; | | 505 | dn->dn_tail = dr; |
512 | } | | 506 | } |
513 | | | | |
514 | designation_debug(dn); | | | |
515 | } | | 507 | } |
516 | | | 508 | |
517 | /* TODO: add support for array subscripts, not only named members */ | | | |
518 | /* | | 509 | /* |
519 | * TODO: This function should not be necessary at all. There is no need to | | 510 | * Starting at the type of the current object, resolve the type of the |
520 | * remove the head of the list. | | 511 | * sub-object by following each designator in the list. |
521 | */ | | 512 | */ |
| | | 513 | static const type_t * |
| | | 514 | designation_look_up(const struct designation *dn, const type_t *tp) |
| | | 515 | { |
| | | 516 | const struct designator *dr; |
| | | 517 | |
| | | 518 | for (dr = dn->dn_head; dr != NULL && tp != NULL; dr = dr->dr_next) |
| | | 519 | tp = designator_look_up(dr, tp); |
| | | 520 | return tp; |
| | | 521 | } |
| | | 522 | |
| | | 523 | |
| | | 524 | |
522 | static void | | 525 | static void |
523 | designation_shift_level(struct designation *dn) | | 526 | designation_reset(struct designation *dn) |
524 | { | | 527 | { |
525 | lint_assert(dn->dn_head != NULL); | | 528 | struct designator *dr, *next; |
526 | | | 529 | |
527 | if (dn->dn_head == dn->dn_tail) { | | 530 | for (dr = dn->dn_head; dr != NULL; dr = next) { |
528 | designator_free(dn->dn_head); | | 531 | next = dr->dr_next; |
529 | dn->dn_head = NULL; | | 532 | designator_free(dr); |
530 | dn->dn_tail = NULL; | | | |
531 | } else { | | | |
532 | struct designator *head = dn->dn_head; | | | |
533 | dn->dn_head = dn->dn_head->dr_next; | | | |
534 | designator_free(head); | | | |
535 | } | | 533 | } |
536 | | | | |
537 | designation_debug(dn); | | | |
538 | } | | 534 | } |
539 | | | 535 | |
540 | | | 536 | |
541 | static struct brace_level * | | 537 | static struct brace_level * |
542 | brace_level_new(type_t *type, type_t *subtype, int remaining, | | 538 | brace_level_new(const type_t *tp, struct brace_level *enclosing) |
543 | struct brace_level *enclosing) | | | |
544 | { | | 539 | { |
545 | struct brace_level *bl = xcalloc(1, sizeof(*bl)); | | 540 | struct brace_level *bl; |
546 | | | 541 | |
547 | bl->bl_type = type; | | 542 | bl = xcalloc(1, sizeof(*bl)); |
548 | bl->bl_subtype = subtype; | | 543 | bl->bl_type = tp; |
549 | bl->bl_remaining = remaining; | | | |
550 | bl->bl_enclosing = enclosing; | | 544 | bl->bl_enclosing = enclosing; |
| | | 545 | if (is_struct_or_union(tp->t_tspec)) |
| | | 546 | bl->bl_next_member = first_named_member(tp); |
551 | | | 547 | |
552 | return bl; | | 548 | return bl; |
553 | } | | 549 | } |
554 | | | 550 | |
555 | static void | | 551 | static void |
556 | brace_level_free(struct brace_level *bl) | | 552 | brace_level_free(struct brace_level *bl) |
557 | { | | 553 | { |
| | | 554 | |
| | | 555 | designation_reset(&bl->bl_designation); |
558 | free(bl); | | 556 | free(bl); |
559 | } | | 557 | } |
560 | | | 558 | |
561 | #ifdef DEBUG | | 559 | #ifdef DEBUG |
562 | /* | | | |
563 | * TODO: only log the top of the stack after each modifying operation | | | |
564 | * | | | |
565 | * TODO: wrap all write accesses to brace_level in setter functions | | | |
566 | */ | | | |
567 | static void | | 560 | static void |
568 | brace_level_debug(const struct brace_level *bl) | | 561 | brace_level_debug(const struct brace_level *bl) |
569 | { | | 562 | { |
570 | if (bl->bl_type != NULL) | | | |
571 | debug_printf("type '%s'", type_name(bl->bl_type)); | | | |
572 | if (bl->bl_type != NULL && bl->bl_subtype != NULL) | | | |
573 | debug_printf(", "); | | | |
574 | if (bl->bl_subtype != NULL) | | | |
575 | debug_printf("subtype '%s'", type_name(bl->bl_subtype)); | | | |
576 | | | 563 | |
577 | if (bl->bl_brace) | | 564 | lint_assert(bl->bl_type != NULL); |
578 | debug_printf(", needs closing brace"); | | 565 | lint_assert(bl->bl_next_member == NULL || |
| | | 566 | !is_unnamed(bl->bl_next_member)); |
| | | 567 | |
| | | 568 | debug_printf("type '%s'", type_name(bl->bl_type)); |
| | | 569 | |
579 | if (bl->bl_array_of_unknown_size) | | 570 | if (bl->bl_array_of_unknown_size) |
580 | debug_printf(", array of unknown size"); | | 571 | debug_printf(", array of unknown size"); |
581 | if (bl->bl_seen_named_member) | | | |
582 | debug_printf(", seen named member"); | | | |
583 | | | 572 | |
584 | const type_t *eff_type = bl->bl_type != NULL | | 573 | if (is_struct_or_union(bl->bl_type->t_tspec) && |
585 | ? bl->bl_type : bl->bl_subtype; | | 574 | bl->bl_next_member != NULL) |
586 | if (eff_type->t_tspec == STRUCT && bl->bl_next_member != NULL) | | | |
587 | debug_printf(", next member '%s'", | | 575 | debug_printf(", next member '%s'", |
588 | bl->bl_next_member->s_name); | | 576 | bl->bl_next_member->s_name); |
| | | 577 | if (bl->bl_type->t_tspec == ARRAY) |
| | | 578 | debug_printf(", next array subscript %zu", |
| | | 579 | bl->bl_array_next_subscript); |
589 | | | 580 | |
590 | debug_printf(", remaining %d\n", bl->bl_remaining); | | 581 | debug_printf("\n"); |
591 | } | | 582 | } |
592 | #else | | 583 | #else |
593 | #define brace_level_debug(bl) do { } while (false) | | 584 | #define brace_level_debug(level) do { } while (false) |
594 | #endif | | 585 | #endif |
595 | | | 586 | |
596 | static void | | 587 | static void |
597 | brace_level_assert_struct_or_union(const struct brace_level *bl) | | 588 | brace_level_remove_designation(struct brace_level *bl) |
598 | { | | 589 | { |
599 | lint_assert(is_struct_or_union(bl->bl_type->t_tspec)); | | 590 | struct designator *dr, *next; |
600 | } | | | |
601 | | | 591 | |
602 | static void | | 592 | for (dr = bl->bl_designation.dn_head; dr != NULL; dr = next) { |
603 | brace_level_assert_array(const struct brace_level *bl) | | 593 | next = dr->dr_next; |
604 | { | | 594 | designator_free(dr); |
605 | lint_assert(bl->bl_type->t_tspec == ARRAY); | | 595 | } |
606 | } | | | |
607 | | | | |
608 | static type_t * | | | |
609 | brace_level_subtype(struct brace_level *bl) | | | |
610 | { | | | |
611 | | | | |
612 | if (bl->bl_subtype != NULL) | | | |
613 | return bl->bl_subtype; | | | |
614 | | | 596 | |
615 | return bl->bl_type; | | 597 | bl->bl_designation.dn_head = NULL; |
| | | 598 | bl->bl_designation.dn_tail = NULL; |
616 | } | | 599 | } |
617 | | | 600 | |
618 | static void | | | |
619 | brace_level_set_array_dimension(struct brace_level *bl, int dim) | | | |
620 | { | | | |
621 | brace_level_assert_array(bl); | | | |
622 | | | | |
623 | debug_step("setting the array size to %d", dim); | | | |
624 | bl->bl_type->t_dim = dim; | | | |
625 | debug_indent(); | | | |
626 | brace_level_debug(bl); | | | |
627 | } | | | |
628 | | | 601 | |
629 | static void | | 602 | static const type_t * |
630 | brace_level_next_member(struct brace_level *bl) | | 603 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) |
631 | { | | 604 | { |
632 | const sym_t *m; | | | |
633 | | | 605 | |
634 | brace_level_assert_struct_or_union(bl); | | 606 | if (bl->bl_next_member == NULL) { |
635 | do { | | 607 | /* too many struct/union initializers */ |
636 | m = bl->bl_next_member = bl->bl_next_member->s_next; | | 608 | error(172); |
637 | /* XXX: can this assertion be made to fail? */ | | 609 | return NULL; |
638 | lint_assert(m != NULL); | | 610 | } |
639 | } while (m->s_bitfield && m->s_name == unnamed); | | | |
640 | | | 611 | |
641 | debug_indent(); | | 612 | lint_assert(!is_unnamed(bl->bl_next_member)); |
642 | brace_level_debug(bl); | | 613 | return sym_type(bl->bl_next_member); |
643 | } | | 614 | } |
644 | | | 615 | |
645 | static const sym_t * | | 616 | static const type_t * |
646 | brace_level_look_up_member(const struct brace_level *bl, const char *name) | | 617 | brace_level_sub_type_array(const struct brace_level *bl) |
647 | { | | 618 | { |
648 | | | 619 | |
649 | brace_level_assert_struct_or_union(bl); | | 620 | if (!bl->bl_type->t_incomplete_array && |
650 | return look_up_member(bl->bl_type->t_str->sou_first_member, name); | | 621 | !bl->bl_omitted_braces && |
| | | 622 | bl->bl_array_next_subscript >= (size_t)bl->bl_type->t_dim) { |
| | | 623 | /* too many array initializers, expected %d */ |
| | | 624 | error(173, bl->bl_type->t_dim); |
| | | 625 | } |
| | | 626 | |
| | | 627 | return bl->bl_type->t_subt; |
651 | } | | 628 | } |
652 | | | 629 | |
653 | static sym_t * | | 630 | static const type_t * |
654 | brace_level_look_up_first_member_named(struct brace_level *bl, | | 631 | brace_level_sub_type_scalar(const struct brace_level *bl) |
655 | const char *name, int *count) | | | |
656 | { | | 632 | { |
657 | sym_t *m; | | | |
658 | | | 633 | |
659 | for (m = bl->bl_type->t_str->sou_first_member; | | 634 | if (bl->bl_scalar_done) { |
660 | m != NULL; m = m->s_next) { | | 635 | /* too many initializers */ |
661 | if (is_unnamed_member(m)) | | 636 | error(174); |
662 | continue; | | | |
663 | if (strcmp(m->s_name, name) != 0) | | | |
664 | continue; | | | |
665 | (*count)++; | | | |
666 | break; | | | |
667 | } | | 637 | } |
668 | | | 638 | |
669 | return m; | | 639 | return bl->bl_type; |
670 | } | | 640 | } |
671 | | | 641 | |
672 | static sym_t * | | 642 | /* Return the type of the sub-object that is currently being initialized. */ |
673 | brace_level_look_up_first_member_unnamed(struct brace_level *bl, int *count) | | 643 | static const type_t * |
| | | 644 | brace_level_sub_type(const struct brace_level *bl) |
674 | { | | 645 | { |
675 | sym_t *m; | | | |
676 | | | 646 | |
677 | brace_level_assert_struct_or_union(bl); | | 647 | if (bl->bl_designation.dn_head != NULL) |
| | | 648 | return designation_look_up(&bl->bl_designation, bl->bl_type); |
678 | | | 649 | |
679 | for (m = bl->bl_type->t_str->sou_first_member; | | 650 | switch (bl->bl_type->t_tspec) { |
680 | m != NULL; m = m->s_next) { | | 651 | case STRUCT: |
681 | if (is_unnamed_member(m)) | | 652 | case UNION: |
682 | continue; | | 653 | return brace_level_sub_type_struct_or_union(bl); |
683 | /* XXX: What is this code for? */ | | 654 | case ARRAY: |
684 | if (++(*count) == 1) { | | 655 | return brace_level_sub_type_array(bl); |
685 | bl->bl_next_member = m; | | 656 | default: |
686 | bl->bl_subtype = m->s_type; | | 657 | return brace_level_sub_type_scalar(bl); |
687 | } | | | |
688 | } | | 658 | } |
689 | | | | |
690 | return m; | | | |
691 | } | | 659 | } |
692 | | | 660 | |
693 | /* TODO: document me */ | | 661 | static void |
694 | /* TODO: think of a better name than 'push' */ | | 662 | brace_level_apply_designation(struct brace_level *bl) |
695 | static bool | | | |
696 | brace_level_push_array(struct brace_level *bl) | | | |
697 | { | | 663 | { |
698 | brace_level_assert_array(bl); | | 664 | const struct designator *dr = bl->bl_designation.dn_head; |
699 | | | 665 | |
700 | if (bl->bl_enclosing->bl_seen_named_member) { | | 666 | if (dr == NULL) |
701 | bl->bl_brace = true; | | 667 | return; |
702 | debug_step("ARRAY, seen named member, needs closing brace"); | | | |
703 | } | | | |
704 | | | 668 | |
705 | if (is_incomplete(bl->bl_type) && | | 669 | designation_debug(&bl->bl_designation); |
706 | bl->bl_enclosing->bl_enclosing != NULL) { | | | |
707 | /* initialization of an incomplete type */ | | | |
708 | error(175); | | | |
709 | return false; | | | |
710 | } | | | |
711 | | | 670 | |
712 | bl->bl_subtype = bl->bl_type->t_subt; | | 671 | switch (bl->bl_type->t_tspec) { |
713 | bl->bl_array_of_unknown_size = is_incomplete(bl->bl_type); | | 672 | case STRUCT: |
714 | bl->bl_remaining = bl->bl_type->t_dim; | | 673 | case UNION: |
715 | debug_step("type '%s' remaining %d", | | 674 | if (dr->dr_name == NULL) |
716 | type_name(bl->bl_type), bl->bl_remaining); | | 675 | return; /* error, silently ignored */ |
717 | return true; | | 676 | bl->bl_next_member = look_up_member(bl->bl_type, dr->dr_name); |
| | | 677 | break; |
| | | 678 | case ARRAY: |
| | | 679 | if (dr->dr_name != NULL) |
| | | 680 | return; /* error, silently ignored */ |
| | | 681 | bl->bl_array_next_subscript = dr->dr_subscript; |
| | | 682 | break; |
| | | 683 | default: |
| | | 684 | break; /* error, silently ignored */ |
| | | 685 | } |
718 | } | | 686 | } |
719 | | | 687 | |
720 | /* | | 688 | /* |
721 | * If the removed element was a structure member, we must go | | 689 | * After initializing a sub-object, advance to the next sub-object. |
722 | * to the next structure member. | | | |
723 | * | | | |
724 | * XXX: Nothing should ever be "removed" at this point. | | | |
725 | * | | 690 | * |
726 | * TODO: think of a better name than 'pop' | | 691 | * C99 6.7.8p17 |
727 | */ | | 692 | */ |
728 | static void | | 693 | static void |
729 | brace_level_pop_item_unnamed(struct brace_level *bl) | | 694 | brace_level_advance(struct brace_level *bl) |
730 | { | | 695 | { |
731 | if (bl->bl_remaining > 0 && bl->bl_type->t_tspec == STRUCT && | | | |
732 | !bl->bl_seen_named_member) { | | | |
733 | brace_level_next_member(bl); | | | |
734 | bl->bl_subtype = bl->bl_next_member->s_type; | | | |
735 | } | | | |
736 | } | | | |
737 | | | 696 | |
738 | static bool | | 697 | switch (bl->bl_type->t_tspec) { |
739 | brace_level_check_too_many_initializers(struct brace_level *bl) | | 698 | case STRUCT: |
740 | { | | 699 | lint_assert(bl->bl_next_member != NULL); |
741 | if (bl->bl_remaining > 0) | | 700 | bl->bl_next_member = skip_unnamed(bl->bl_next_member->s_next); |
742 | return true; | | 701 | break; |
743 | /* | | 702 | case UNION: |
744 | * FIXME: even with named members, there can be too many initializers | | 703 | bl->bl_next_member = NULL; |
745 | */ | | 704 | break; |
746 | if (bl->bl_array_of_unknown_size || bl->bl_seen_named_member) | | 705 | case ARRAY: |
747 | return true; | | 706 | bl->bl_array_next_subscript++; |
748 | | | 707 | break; |
749 | tspec_t t = bl->bl_type->t_tspec; | | 708 | default: |
750 | if (t == ARRAY) { | | 709 | bl->bl_scalar_done = true; |
751 | /* too many array initializers, expected %d */ | | 710 | break; |
752 | error(173, bl->bl_type->t_dim); | | | |
753 | } else if (is_struct_or_union(t)) { | | | |
754 | /* too many struct/union initializers */ | | | |
755 | error(172); | | | |
756 | } else { | | | |
757 | /* too many initializers */ | | | |
758 | error(174); | | | |
759 | } | | 711 | } |
760 | return false; | | | |
761 | } | | | |
762 | | | | |
763 | /* Extend an array of unknown size by one element */ | | | |
764 | static void | | | |
765 | brace_level_extend_if_array_of_unknown_size(struct brace_level *bl) | | | |
766 | { | | | |
767 | | | | |
768 | if (bl->bl_remaining != 0) | | | |
769 | return; | | | |
770 | /* | | | |
771 | * XXX: According to the function name, there should be a 'return' if | | | |
772 | * bl_array_of_unknown_size is false. There's probably a test missing | | | |
773 | * for that case. | | | |
774 | */ | | | |
775 | | | | |
776 | /* | | | |
777 | * The only place where an incomplete array may appear is at the | | | |
778 | * outermost aggregate bl of the object to be initialized. | | | |
779 | */ | | | |
780 | lint_assert(bl->bl_enclosing->bl_enclosing == NULL); | | | |
781 | lint_assert(bl->bl_type->t_tspec == ARRAY); | | | |
782 | | | | |
783 | debug_step("extending array of unknown size '%s'", | | | |
784 | type_name(bl->bl_type)); | | | |
785 | bl->bl_remaining = 1; | | | |
786 | bl->bl_type->t_dim++; | | | |
787 | setcomplete(bl->bl_type, true); | | | |
788 | | | | |
789 | debug_step("extended type is '%s'", type_name(bl->bl_type)); | | | |
790 | } | | 712 | } |
791 | | | 713 | |
792 | | | 714 | |
793 | static struct initialization * | | 715 | static struct initialization * |
794 | initialization_new(sym_t *sym) | | 716 | initialization_new(sym_t *sym) |
795 | { | | 717 | { |
796 | struct initialization *in = xcalloc(1, sizeof(*in)); | | 718 | struct initialization *in; |
797 | | | 719 | |
| | | 720 | in = xcalloc(1, sizeof(*in)); |
798 | in->in_sym = sym; | | 721 | in->in_sym = sym; |
799 | | | 722 | |
800 | return in; | | 723 | return in; |
801 | } | | 724 | } |
802 | | | 725 | |
803 | static void | | 726 | static void |
804 | initialization_free(struct initialization *in) | | 727 | initialization_free(struct initialization *in) |
805 | { | | 728 | { |
806 | struct brace_level *bl, *next; | | 729 | struct brace_level *bl, *next; |
807 | | | 730 | |
808 | for (bl = in->in_brace_level; bl != NULL; bl = next) { | | 731 | for (bl = in->in_brace_level; bl != NULL; bl = next) { |
809 | next = bl->bl_enclosing; | | 732 | next = bl->bl_enclosing; |
810 | brace_level_free(bl); | | 733 | brace_level_free(bl); |
811 | } | | 734 | } |
812 | | | 735 | |
813 | free(in); | | 736 | free(in); |
814 | } | | 737 | } |
815 | | | 738 | |
816 | #ifdef DEBUG | | 739 | #ifdef DEBUG |
817 | /* | | | |
818 | * TODO: only call debug_initstack after each push/pop. | | | |
819 | */ | | | |
820 | static void | | 740 | static void |
821 | initialization_debug(const struct initialization *in) | | 741 | initialization_debug(const struct initialization *in) |
822 | { | | 742 | { |
| | | 743 | size_t i; |
| | | 744 | const struct brace_level *bl; |
| | | 745 | |
823 | if (in->in_brace_level == NULL) { | | 746 | if (in->in_brace_level == NULL) { |
824 | debug_step("no brace level in the current initialization"); | | 747 | debug_step("no brace level"); |
825 | return; | | 748 | return; |
826 | } | | 749 | } |
827 | | | 750 | |
828 | size_t i = 0; | | 751 | i = 0; |
829 | for (const struct brace_level *bl = in->in_brace_level; | | 752 | for (bl = in->in_brace_level; bl != NULL; bl = bl->bl_enclosing) { |
830 | bl != NULL; bl = bl->bl_enclosing) { | | | |
831 | debug_indent(); | | 753 | debug_indent(); |
832 | debug_printf("brace level %zu: ", i); | | 754 | debug_printf("brace level %zu: ", i); |
833 | brace_level_debug(bl); | | 755 | brace_level_debug(bl); |
834 | i++; | | 756 | i++; |
835 | } | | 757 | } |
836 | } | | 758 | } |
837 | #else | | 759 | #else |
838 | #define initialization_debug(in) do { } while (false) | | 760 | #define initialization_debug(in) do { } while (false) |
839 | #endif | | 761 | #endif |
840 | | | 762 | |
841 | /* | | 763 | /* |
842 | * Initialize the initialization stack by putting an entry for the object | | 764 | * Return the type of the object or sub-object that is currently being |
843 | * which is to be initialized on it. | | 765 | * initialized. |
844 | * | | | |
845 | * TODO: merge into initialization_new if possible | | | |
846 | */ | | 766 | */ |
847 | static void | | 767 | static const type_t * |
848 | initialization_init(struct initialization *in) | | 768 | initialization_sub_type(struct initialization *in) |
849 | { | | | |
850 | if (in->in_err) | | | |
851 | return; | | | |
852 | | | | |
853 | debug_enter(); | | | |
854 | | | | |
855 | /* | | | |
856 | * If the type which is to be initialized is an incomplete array, | | | |
857 | * it must be duplicated. | | | |
858 | */ | | | |
859 | if (in->in_sym->s_type->t_tspec == ARRAY && is_incomplete(in->in_sym->s_type)) | | | |
860 | in->in_sym->s_type = duptyp(in->in_sym->s_type); | | | |
861 | /* TODO: does 'duptyp' create a memory leak? */ | | | |
862 | | | | |
863 | in->in_brace_level = brace_level_new(NULL, in->in_sym->s_type, 1, NULL); | | | |
864 | | | | |
865 | initialization_debug(in); | | | |
866 | debug_leave(); | | | |
867 | } | | | |
868 | | | | |
869 | static void | | | |
870 | initialization_set_error(struct initialization *in) | | | |
871 | { | | 769 | { |
872 | in->in_err = true; | | 770 | const type_t *tp; |
873 | } | | | |
874 | | | 771 | |
875 | /* TODO: document me */ | | 772 | tp = in->in_brace_level != NULL |
876 | /* TODO: think of a better name than 'push' */ | | 773 | ? brace_level_sub_type(in->in_brace_level) |
877 | static bool | | 774 | : in->in_sym->s_type; |
878 | initialization_push_struct_or_union(struct initialization *in) | | 775 | if (tp == NULL) |
879 | { | | 776 | in->in_err = true; |
880 | struct brace_level *bl = in->in_brace_level; | | 777 | return tp; |
881 | int cnt; | | | |
882 | sym_t *m; | | | |
883 | | | | |
884 | if (is_incomplete(bl->bl_type)) { | | | |
885 | /* initialization of an incomplete type */ | | | |
886 | error(175); | | | |
887 | initialization_set_error(in); | | | |
888 | return false; | | | |
889 | } | | | |
890 | | | | |
891 | cnt = 0; | | | |
892 | designation_debug(&in->in_designation); | | | |
893 | debug_step("lookup for '%s'%s", | | | |
894 | type_name(bl->bl_type), | | | |
895 | bl->bl_seen_named_member ? ", seen named member" : ""); | | | |
896 | | | | |
897 | if (in->in_designation.dn_head != NULL) | | | |
898 | m = brace_level_look_up_first_member_named(bl, | | | |
899 | in->in_designation.dn_head->dr_name, &cnt); | | | |
900 | else | | | |
901 | m = brace_level_look_up_first_member_unnamed(bl, &cnt); | | | |
902 | | | | |
903 | if (in->in_designation.dn_head != NULL) { | | | |
904 | if (m == NULL) { | | | |
905 | debug_step("pop struct"); | | | |
906 | return true; | | | |
907 | } | | | |
908 | bl->bl_next_member = m; | | | |
909 | bl->bl_subtype = m->s_type; | | | |
910 | bl->bl_seen_named_member = true; | | | |
911 | debug_step("named member '%s'", | | | |
912 | in->in_designation.dn_head->dr_name); | | | |
913 | designation_shift_level(&in->in_designation); | | | |
914 | cnt = bl->bl_type->t_tspec == STRUCT ? 2 : 1; | | | |
915 | } | | | |
916 | bl->bl_brace = true; | | | |
917 | debug_step("unnamed element with type '%s'%s", | | | |
918 | type_name( | | | |
919 | bl->bl_type != NULL ? bl->bl_type : bl->bl_subtype), | | | |
920 | bl->bl_brace ? ", needs closing brace" : ""); | | | |
921 | if (cnt == 0) { | | | |
922 | /* cannot init. struct/union with no named member */ | | | |
923 | error(179); | | | |
924 | initialization_set_error(in); | | | |
925 | return false; | | | |
926 | } | | | |
927 | bl->bl_remaining = bl->bl_type->t_tspec == STRUCT ? cnt : 1; | | | |
928 | return false; | | | |
929 | } | | 778 | } |
930 | | | 779 | |
931 | static void | | 780 | static void |
932 | initialization_end_brace_level(struct initialization *in) | | 781 | initialization_begin_brace_level(struct initialization *in) |
933 | { | | 782 | { |
934 | struct brace_level *bl = in->in_brace_level; | | 783 | const type_t *tp; |
935 | in->in_brace_level = bl->bl_enclosing; | | | |
936 | brace_level_free(bl); | | | |
937 | } | | | |
938 | | | 784 | |
939 | /* TODO: document me */ | | 785 | if (in->in_err) |
940 | /* TODO: think of a better name than 'push' */ | | 786 | return; |
941 | static void | | | |
942 | initialization_push(struct initialization *in) | | | |
943 | { | | | |
944 | struct brace_level *bl; | | | |
945 | | | 787 | |
946 | debug_enter(); | | 788 | debug_enter(); |
947 | | | 789 | |
948 | brace_level_extend_if_array_of_unknown_size(in->in_brace_level); | | 790 | tp = initialization_sub_type(in); |
949 | | | 791 | if (tp == NULL) { |
950 | bl = in->in_brace_level; | | 792 | in->in_err = true; |
951 | lint_assert(bl->bl_remaining > 0); | | 793 | goto done; |
| | | 794 | } |
952 | | | 795 | |
953 | in->in_brace_level = brace_level_new(brace_level_subtype(bl), NULL, 0, | | 796 | if (tflag && in->in_brace_level == NULL) |
954 | bl); | | 797 | check_no_auto_aggregate(in->in_sym); |
955 | lint_assert(in->in_brace_level->bl_type != NULL); | | | |
956 | lint_assert(in->in_brace_level->bl_type->t_tspec != FUNC); | | | |
957 | | | 798 | |
958 | again: | | 799 | if (tflag && tp->t_tspec == UNION) { |
959 | bl = in->in_brace_level; | | 800 | /* initialization of union is illegal in traditional C */ |
| | | 801 | warning(238); |
| | | 802 | } |
960 | | | 803 | |
961 | debug_step("expecting type '%s'", type_name(bl->bl_type)); | | 804 | if (tp->t_tspec == STRUCT && tp->t_str->sou_incomplete) { |
962 | lint_assert(bl->bl_type != NULL); | | 805 | /* TODO: add type information */ |
963 | switch (bl->bl_type->t_tspec) { | | 806 | /* initialization of an incomplete type */ |
964 | case ARRAY: | | 807 | error(175); |
965 | if (in->in_designation.dn_head != NULL) { | | 808 | in->in_err = true; |
966 | debug_step("pop array, named member '%s'%s", | | 809 | goto done; |
967 | in->in_designation.dn_head->dr_name, | | 810 | } |
968 | bl->bl_brace ? ", needs closing brace" : ""); | | | |
969 | goto pop; | | | |
970 | } | | | |
971 | | | 811 | |
972 | if (!brace_level_push_array(bl)) | | 812 | if (in->in_brace_level != NULL) |
973 | initialization_set_error(in); | | 813 | brace_level_apply_designation(in->in_brace_level); |
974 | break; | | | |
975 | | | 814 | |
976 | case UNION: | | 815 | in->in_brace_level = brace_level_new(tp, in->in_brace_level); |
977 | if (tflag) | | | |
978 | /* initialization of union is illegal in trad. C */ | | | |
979 | warning(238); | | | |
980 | /* FALLTHROUGH */ | | | |
981 | case STRUCT: | | | |
982 | if (initialization_push_struct_or_union(in)) | | | |
983 | goto pop; | | | |
984 | break; | | | |
985 | default: | | | |
986 | if (in->in_designation.dn_head != NULL) { | | | |
987 | debug_step("pop scalar"); | | | |
988 | pop: | | | |
989 | initialization_end_brace_level(in); | | | |
990 | goto again; | | | |
991 | } | | | |
992 | /* The initialization stack now expects a single scalar. */ | | | |
993 | bl->bl_remaining = 1; | | | |
994 | break; | | | |
995 | } | | | |
996 | | | 816 | |
| | | 817 | done: |
997 | initialization_debug(in); | | 818 | initialization_debug(in); |
998 | debug_leave(); | | 819 | debug_leave(); |
999 | } | | 820 | } |
1000 | | | 821 | |
1001 | /* TODO: document me */ | | 822 | /* C99 6.7.8p22 */ |
1002 | static void | | 823 | static void |
1003 | initialization_pop_item_named(struct initialization *in, const char *name) | | 824 | initialization_set_size_of_unknown_array(struct initialization *in) |
1004 | { | | 825 | { |
1005 | struct brace_level *bl = in->in_brace_level; | | | |
1006 | const sym_t *m; | | | |
1007 | | | | |
1008 | /* | | | |
1009 | * TODO: fix wording of the debug message; this doesn't seem to be | | | |
1010 | * related to initializing the named member. | | | |
1011 | */ | | | |
1012 | debug_step("initializing named member '%s'", name); | | | |
1013 | | | 826 | |
1014 | if (!is_struct_or_union(bl->bl_type->t_tspec)) { | | 827 | if (in->in_sym->s_type->t_incomplete_array && |
1015 | /* syntax error '%s' */ | | 828 | in->in_brace_level->bl_enclosing == NULL) |
1016 | error(249, "named member must only be used with struct/union"); | | 829 | update_type_of_array_of_unknown_size(in->in_sym, |
1017 | initialization_set_error(in); | | 830 | in->in_brace_level->bl_array_next_subscript); |
1018 | return; | | | |
1019 | } | | | |
1020 | | | | |
1021 | m = brace_level_look_up_member(bl, name); | | | |
1022 | if (m == NULL) { | | | |
1023 | /* TODO: add type information to the message */ | | | |
1024 | /* undefined struct/union member: %s */ | | | |
1025 | error(101, name); | | | |
1026 | | | | |
1027 | designation_shift_level(&in->in_designation); | | | |
1028 | bl->bl_seen_named_member = true; | | | |
1029 | return; | | | |
1030 | } | | | |
1031 | | | | |
1032 | debug_step("found matching member"); | | | |
1033 | bl->bl_subtype = m->s_type; | | | |
1034 | /* XXX: why ++? */ | | | |
1035 | bl->bl_remaining++; | | | |
1036 | /* XXX: why is bl_seen_named_member not set? */ | | | |
1037 | designation_shift_level(&in->in_designation); | | | |
1038 | } | | 831 | } |
1039 | | | 832 | |
1040 | /* TODO: think of a better name than 'pop' */ | | | |
1041 | static void | | 833 | static void |
1042 | initialization_pop_item(struct initialization *in) | | 834 | initialization_end_brace_level(struct initialization *in) |
1043 | { | | 835 | { |
1044 | struct brace_level *bl; | | 836 | struct brace_level *bl; |
1045 | | | 837 | |
| | | 838 | if (in->in_err) |
| | | 839 | return; |
| | | 840 | |
1046 | debug_enter(); | | 841 | debug_enter(); |
1047 | | | 842 | |
1048 | bl = in->in_brace_level; | | 843 | initialization_set_size_of_unknown_array(in); |
1049 | debug_indent(); | | | |
1050 | debug_printf("popping: "); | | | |
1051 | brace_level_debug(bl); | | | |
1052 | | | 844 | |
| | | 845 | bl = in->in_brace_level; |
1053 | in->in_brace_level = bl->bl_enclosing; | | 846 | in->in_brace_level = bl->bl_enclosing; |
1054 | brace_level_free(bl); | | 847 | brace_level_free(bl); |
1055 | bl = in->in_brace_level; | | | |
1056 | lint_assert(bl != NULL); | | | |
1057 | | | | |
1058 | bl->bl_remaining--; | | | |
1059 | lint_assert(bl->bl_remaining >= 0); | | | |
1060 | debug_step("%d elements remaining", bl->bl_remaining); | | | |
1061 | | | | |
1062 | if (in->in_designation.dn_head != NULL && in->in_designation.dn_head->dr_name != NULL) | | | |
1063 | initialization_pop_item_named(in, in->in_designation.dn_head->dr_name); | | | |
1064 | else | | | |
1065 | brace_level_pop_item_unnamed(bl); | | | |
1066 | | | | |
1067 | initialization_debug(in); | | | |
1068 | debug_leave(); | | | |
1069 | } | | | |
1070 | | | | |
1071 | /* | | | |
1072 | * Take all entries which cannot be used for further initializers from the | | | |
1073 | * stack, but do this only if they do not require a closing brace. | | | |
1074 | */ | | | |
1075 | /* TODO: think of a better name than 'pop' */ | | | |
1076 | static void | | | |
1077 | initialization_pop_nobrace(struct initialization *in) | | | |
1078 | { | | | |
1079 | | | | |
1080 | debug_enter(); | | | |
1081 | while (!in->in_brace_level->bl_brace && | | | |
1082 | in->in_brace_level->bl_remaining == 0 && | | | |
1083 | !in->in_brace_level->bl_array_of_unknown_size) | | | |
1084 | initialization_pop_item(in); | | | |
1085 | debug_leave(); | | | |
1086 | } | | | |
1087 | | | | |
1088 | /* | | | |
1089 | * Process a '{' in an initializer by starting the initialization of the | | | |
1090 | * nested data structure, with bl_type being the bl_subtype of the outer | | | |
1091 | * initialization level. | | | |
1092 | */ | | | |
1093 | static void | | | |
1094 | initialization_next_brace(struct initialization *in) | | | |
1095 | { | | | |
1096 | | | 848 | |
1097 | debug_enter(); | | 849 | if (in->in_brace_level != NULL) { |
1098 | initialization_debug(in); | | 850 | brace_level_advance(in->in_brace_level); |
1099 | | | 851 | brace_level_remove_designation(in->in_brace_level); |
1100 | if (!in->in_err && | | | |
1101 | !brace_level_check_too_many_initializers(in->in_brace_level)) | | | |
1102 | initialization_set_error(in); | | | |
1103 | | | | |
1104 | if (!in->in_err) | | | |
1105 | initialization_push(in); | | | |
1106 | | | | |
1107 | if (!in->in_err) { | | | |
1108 | in->in_brace_level->bl_brace = true; | | | |
1109 | designation_debug(&in->in_designation); | | | |
1110 | if (in->in_brace_level->bl_type != NULL) | | | |
1111 | debug_step("expecting type '%s'", | | | |
1112 | type_name(in->in_brace_level->bl_type)); | | | |
1113 | } | | 852 | } |
1114 | | | 853 | |
1115 | initialization_debug(in); | | 854 | initialization_debug(in); |
1116 | debug_leave(); | | 855 | debug_leave(); |
1117 | } | | 856 | } |
1118 | | | 857 | |
1119 | static void | | 858 | static void |
1120 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *bl) | | 859 | initialization_add_designator(struct initialization *in, |
| | | 860 | const char *name, size_t subscript) |
1121 | { | | 861 | { |
1122 | if (!tflag) | | | |
1123 | return; | | | |
1124 | if (!(sclass == AUTO || sclass == REG)) | | | |
1125 | return; | | | |
1126 | if (!(bl->bl_enclosing == NULL)) | | | |
1127 | return; | | | |
1128 | if (is_scalar(bl->bl_subtype->t_tspec)) | | | |
1129 | return; | | | |
1130 | | | 862 | |
1131 | /* no automatic aggregate initialization in trad. C */ | | | |
1132 | warning(188); | | | |
1133 | } | | | |
1134 | | | | |
1135 | static void | | | |
1136 | initialization_lbrace(struct initialization *in) | | | |
1137 | { | | | |
1138 | if (in->in_err) | | 863 | if (in->in_err) |
1139 | return; | | 864 | return; |
1140 | | | 865 | |
1141 | debug_enter(); | | 866 | lint_assert(in->in_brace_level != NULL); |
1142 | initialization_debug(in); | | 867 | designation_add(&in->in_brace_level->bl_designation, name, subscript); |
1143 | | | | |
1144 | check_no_auto_aggregate(in->in_sym->s_scl, in->in_brace_level); | | | |
1145 | | | | |
1146 | /* | | | |
1147 | * Remove all entries which cannot be used for further initializers | | | |
1148 | * and do not expect a closing brace. | | | |
1149 | */ | | | |
1150 | initialization_pop_nobrace(in); | | | |
1151 | | | | |
1152 | initialization_next_brace(in); | | | |
1153 | | | | |
1154 | initialization_debug(in); | | | |
1155 | debug_leave(); | | | |
1156 | } | | 868 | } |
1157 | | | 869 | |
1158 | /* | | | |
1159 | * Process a '}' in an initializer by finishing the current level of the | | | |
1160 | * initialization stack. | | | |
1161 | * | | | |
1162 | * Take all entries, including the first which requires a closing brace, | | | |
1163 | * from the stack. | | | |
1164 | */ | | | |
1165 | static void | | 870 | static void |
1166 | initialization_rbrace(struct initialization *in) | | 871 | initialization_remove_designation(struct initialization *in) |
1167 | { | | 872 | { |
1168 | bool brace; | | | |
1169 | | | | |
1170 | if (in->in_err) | | | |
1171 | return; | | | |
1172 | | | 873 | |
1173 | debug_enter(); | | 874 | if (in->in_brace_level != NULL) |
1174 | do { | | 875 | brace_level_remove_designation(in->in_brace_level); |
1175 | brace = in->in_brace_level->bl_brace; | | | |
1176 | /* TODO: improve wording of the debug message */ | | | |
1177 | debug_step("loop brace=%d", brace); | | | |
1178 | initialization_pop_item(in); | | | |
1179 | } while (!brace); | | | |
1180 | initialization_debug(in); | | | |
1181 | debug_leave(); | | | |
1182 | } | | 876 | } |
1183 | | | 877 | |
1184 | /* | | 878 | /* |
1185 | * A sub-object of an array is initialized using a designator. This does not | | 879 | * An object with automatic storage duration that has a single initializer |
1186 | * have to be an array element directly, it can also be used to initialize | | 880 | * expression without braces and is not an array is initialized by delegating |
1187 | * only a sub-object of the array element. | | 881 | * to the ASSIGN operator. |
1188 | * | | | |
1189 | * C99 example: struct { int member[4]; } var = { [2] = 12345 }; | | | |
1190 | * | | | |
1191 | * GNU example: struct { int member[4]; } var = { [1 ... 3] = 12345 }; | | | |
1192 | * | | | |
1193 | * TODO: test the following initialization with an outer and an inner type: | | | |
1194 | * | | | |
1195 | * .deeply[0].nested = { | | | |
1196 | * .deeply[1].nested = { | | | |
1197 | * 12345, | | | |
1198 | * }, | | | |
1199 | * } | | | |
1200 | */ | | 882 | */ |
1201 | static void | | 883 | static bool |
1202 | initialization_add_designator_subscript(struct initialization *in, | | 884 | initialization_expr_using_assign(struct initialization *in, tnode_t *rn) |
1203 | range_t range) | | | |
1204 | { | | 885 | { |
1205 | struct brace_level *bl; | | 886 | tnode_t *ln, *tn; |
1206 | | | 887 | |
1207 | debug_enter(); | | 888 | if (!has_automatic_storage_duration(in->in_sym)) |
1208 | if (range.lo == range.hi) | | 889 | return false; |
1209 | debug_step("subscript is %zu", range.hi); | | 890 | if (in->in_brace_level != NULL) |
1210 | else | | 891 | return false; |
1211 | debug_step("subscript range is %zu ... %zu", | | 892 | if (in->in_sym->s_type->t_tspec == ARRAY) |
1212 | range.lo, range.hi); | | 893 | return false; |
1213 | | | 894 | |
1214 | /* XXX: This call is wrong here, it must be somewhere else. */ | | 895 | debug_step("handing over to ASSIGN"); |
1215 | initialization_pop_nobrace(in); | | | |
1216 | | | 896 | |
1217 | bl = in->in_brace_level; | | 897 | ln = new_name_node(in->in_sym, 0); |
1218 | if (bl->bl_array_of_unknown_size) { | | 898 | ln->tn_type = tduptyp(ln->tn_type); |
1219 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ | | 899 | ln->tn_type->t_const = false; |
1220 | int auto_dim = (int)range.hi; | | | |
1221 | if (auto_dim > bl->bl_type->t_dim) | | | |
1222 | brace_level_set_array_dimension(bl, auto_dim); | | | |
1223 | } | | | |
1224 | | | 900 | |
1225 | debug_leave(); | | 901 | tn = build(ASSIGN, ln, rn); |
| | | 902 | expr(tn, false, false, false, false); |
| | | 903 | |
| | | 904 | return true; |
1226 | } | | 905 | } |
1227 | | | 906 | |
1228 | /* Initialize a character array or wchar_t array with a string literal. */ | | 907 | /* Initialize a character array or wchar_t array with a string literal. */ |
1229 | static bool | | 908 | static bool |
1230 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) | | 909 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) |
1231 | { | | 910 | { |
1232 | struct brace_level *bl; | | 911 | struct brace_level *bl; |
| | | 912 | const type_t *tp; |
1233 | strg_t *strg; | | 913 | strg_t *strg; |
1234 | | | 914 | |
1235 | if (tn->tn_op != STRING) | | 915 | if (tn->tn_op != STRING) |
1236 | return false; | | 916 | return false; |
1237 | | | 917 | |
1238 | debug_enter(); | | | |
1239 | | | | |
1240 | bl = in->in_brace_level; | | 918 | bl = in->in_brace_level; |
| | | 919 | tp = initialization_sub_type(in); |
1241 | strg = tn->tn_string; | | 920 | strg = tn->tn_string; |
1242 | | | 921 | |
1243 | /* | | 922 | if (!is_string_array(tp, strg->st_tspec)) |
1244 | * Check if we have an array type which can be initialized by | | 923 | return false; |
1245 | * the string. | | 924 | if (bl != NULL && tp->t_tspec != ARRAY && |
1246 | */ | | 925 | bl->bl_array_next_subscript != 0) |
1247 | if (is_string_array(bl->bl_subtype, strg->st_tspec)) { | | 926 | return false; |
1248 | debug_step("subtype is an array"); | | | |
1249 | | | | |
1250 | /* Put the array at top of stack */ | | | |
1251 | initialization_push(in); | | | |
1252 | bl = in->in_brace_level; | | | |
1253 | | | | |
1254 | } else if (is_string_array(bl->bl_type, strg->st_tspec)) { | | | |
1255 | debug_step("type is an array"); | | | |
1256 | | | | |
1257 | /* | | | |
1258 | * If the array is already partly initialized, we are | | | |
1259 | * wrong here. | | | |
1260 | */ | | | |
1261 | if (bl->bl_remaining != bl->bl_type->t_dim) | | | |
1262 | goto nope; | | | |
1263 | } else | | | |
1264 | goto nope; | | | |
1265 | | | | |
1266 | if (bl->bl_array_of_unknown_size) { | | | |
1267 | bl->bl_array_of_unknown_size = false; | | | |
1268 | bl->bl_type->t_dim = (int)(strg->st_len + 1); | | | |
1269 | setcomplete(bl->bl_type, true); | | | |
1270 | } else { | | | |
1271 | /* | | | |
1272 | * TODO: check for buffer overflow in the object to be | | | |
1273 | * initialized | | | |
1274 | */ | | | |
1275 | /* XXX: double-check for off-by-one error */ | | | |
1276 | if (bl->bl_type->t_dim < (int)strg->st_len) { | | | |
1277 | /* non-null byte ignored in string initializer */ | | | |
1278 | warning(187); | | | |
1279 | } | | | |
1280 | | | 927 | |
1281 | /* | | 928 | if (bl != NULL && tp->t_dim < (int)strg->st_len) { |
1282 | * TODO: C99 6.7.8p14 allows a string literal to be enclosed | | 929 | /* non-null byte ignored in string initializer */ |
1283 | * in optional redundant braces, just like scalars. Add tests | | 930 | warning(187); |
1284 | * for this. | | | |
1285 | */ | | | |
1286 | } | | 931 | } |
1287 | | | 932 | |
1288 | /* In every case the array is initialized completely. */ | | 933 | if (tp == in->in_sym->s_type && tp->t_incomplete_array) { |
1289 | bl->bl_remaining = 0; | | 934 | if (bl != NULL) { |
| | | 935 | bl->bl_array_next_subscript = strg->st_len + 1; |
| | | 936 | /* see initialization_set_size_of_unknown_array */ |
| | | 937 | } else |
| | | 938 | update_type_of_array_of_unknown_size(in->in_sym, |
| | | 939 | strg->st_len + 1); |
| | | 940 | } |
1290 | | | 941 | |
1291 | initialization_debug(in); | | | |
1292 | debug_leave(); | | | |
1293 | return true; | | 942 | return true; |
1294 | nope: | | | |
1295 | debug_leave(); | | | |
1296 | return false; | | | |
1297 | } | | 943 | } |
1298 | | | 944 | |
1299 | /* | | 945 | /* |
1300 | * Initialize a non-array object with automatic storage duration and only a | | 946 | * Initialize a single sub-object as part of the currently ongoing |
1301 | * single initializer expression without braces by delegating to ASSIGN. | | 947 | * initialization. |
1302 | */ | | 948 | */ |
1303 | static bool | | 949 | static void |
1304 | initialization_init_using_assign(struct initialization *in, tnode_t *rn) | | 950 | initialization_expr(struct initialization *in, tnode_t *tn) |
1305 | { | | 951 | { |
1306 | tnode_t *ln, *tn; | | 952 | const type_t *tp; |
1307 | | | | |
1308 | if (in->in_sym->s_type->t_tspec == ARRAY) | | | |
1309 | return false; | | | |
1310 | if (in->in_brace_level->bl_enclosing != NULL) | | | |
1311 | return false; | | | |
1312 | | | 953 | |
1313 | debug_step("handing over to ASSIGN"); | | 954 | if (in->in_err) |
| | | 955 | return; |
1314 | | | 956 | |
1315 | ln = new_name_node(in->in_sym, 0); | | 957 | if (in->in_brace_level != NULL && |
1316 | ln->tn_type = tduptyp(ln->tn_type); | | 958 | in->in_brace_level->bl_omitted_braces) |
1317 | ln->tn_type->t_const = false; | | 959 | return; |
1318 | | | 960 | |
1319 | tn = build(ASSIGN, ln, rn); | | 961 | debug_enter(); |
1320 | expr(tn, false, false, false, false); | | | |
1321 | | | 962 | |
1322 | /* XXX: why not clean up the initstack here already? */ | | 963 | if (tn == NULL) |
1323 | return true; | | 964 | goto advance; |
1324 | } | | 965 | if (initialization_expr_using_assign(in, tn)) |
| | | 966 | goto done; |
| | | 967 | if (initialization_init_array_using_string(in, tn)) |
| | | 968 | goto advance; |
1325 | | | 969 | |
1326 | /* TODO: document me, or think of a better name */ | | 970 | if (in->in_brace_level != NULL) |
1327 | static void | | 971 | brace_level_apply_designation(in->in_brace_level); |
1328 | initialization_next_nobrace(struct initialization *in, tnode_t *tn) | | 972 | tp = initialization_sub_type(in); |
1329 | { | | 973 | if (tp == NULL) |
1330 | debug_enter(); | | 974 | goto done; |
1331 | | | 975 | |
1332 | if (in->in_brace_level->bl_type == NULL && | | 976 | if (in->in_brace_level == NULL && !is_scalar(tp->t_tspec)) { |
1333 | !is_scalar(in->in_brace_level->bl_subtype->t_tspec)) { | | | |
1334 | /* {}-enclosed initializer required */ | | 977 | /* {}-enclosed initializer required */ |
1335 | error(181); | | 978 | error(181); |
1336 | /* XXX: maybe set initerr here */ | | 979 | goto done; |
1337 | } | | 980 | } |
1338 | | | 981 | |
1339 | if (!in->in_err && | | 982 | /* |
1340 | !brace_level_check_too_many_initializers(in->in_brace_level)) | | 983 | * Hack to accept initializations with omitted braces, see |
1341 | initialization_set_error(in); | | 984 | * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and |
1342 | | | 985 | * Clang already warn about this at level -Wall, there is no point |
1343 | while (!in->in_err) { | | 986 | * in letting lint check this again. |
1344 | struct brace_level *bl = in->in_brace_level; | | 987 | */ |
1345 | | | 988 | if (is_scalar(tn->tn_type->t_tspec) && |
1346 | if (tn->tn_type->t_tspec == STRUCT && | | 989 | tp->t_tspec == ARRAY && |
1347 | bl->bl_type == tn->tn_type && | | 990 | in->in_brace_level != NULL) { |
1348 | bl->bl_enclosing != NULL && | | 991 | in->in_brace_level->bl_omitted_braces = true; |
1349 | bl->bl_enclosing->bl_enclosing != NULL) { | | 992 | goto done; |
1350 | bl->bl_brace = false; | | | |
1351 | bl->bl_remaining = 1; /* the struct itself */ | | | |
1352 | break; | | | |
1353 | } | | | |
1354 | | | | |
1355 | if (bl->bl_type != NULL && | | | |
1356 | is_scalar(bl->bl_type->t_tspec)) | | | |
1357 | break; | | | |
1358 | initialization_push(in); | | | |
1359 | } | | 993 | } |
1360 | | | 994 | |
| | | 995 | debug_step("expecting '%s', expression has '%s'", |
| | | 996 | type_name(tp), type_name(tn->tn_type)); |
| | | 997 | check_init_expr(tp, in->in_sym, tn); |
| | | 998 | |
| | | 999 | advance: |
| | | 1000 | if (in->in_brace_level != NULL) |
| | | 1001 | brace_level_advance(in->in_brace_level); |
| | | 1002 | done: |
| | | 1003 | initialization_remove_designation(in); |
1361 | initialization_debug(in); | | 1004 | initialization_debug(in); |
1362 | debug_leave(); | | 1005 | debug_leave(); |
1363 | } | | 1006 | } |
1364 | | | 1007 | |
1365 | static void | | | |
1366 | initialization_expr(struct initialization *in, tnode_t *tn) | | | |
1367 | { | | | |
1368 | | | | |
1369 | debug_enter(); | | | |
1370 | initialization_debug(in); | | | |
1371 | designation_debug(&in->in_designation); | | | |
1372 | debug_step("expr:"); | | | |
1373 | debug_node(tn, debug_ind + 1); | | | |
1374 | | | 1008 | |
1375 | if (in->in_err || tn == NULL) | | 1009 | static struct initialization *init; |
1376 | goto done; | | | |
1377 | | | | |
1378 | if (has_automatic_storage_duration(in->in_sym) && | | | |
1379 | initialization_init_using_assign(in, tn)) | | | |
1380 | goto done; | | | |
1381 | | | | |
1382 | initialization_pop_nobrace(in); | | | |
1383 | | | | |
1384 | if (initialization_init_array_using_string(in, tn)) { | | | |
1385 | debug_step("after initializing the string:"); | | | |
1386 | goto done_debug; | | | |
1387 | } | | | |
1388 | | | | |
1389 | initialization_next_nobrace(in, tn); | | | |
1390 | if (in->in_err || tn == NULL) | | | |
1391 | goto done_debug; | | | |
1392 | | | | |
1393 | /* Using initsym here is better than nothing. */ | | | |
1394 | check_init_expr(in->in_brace_level->bl_type, in->in_sym, tn); | | | |
1395 | | | | |
1396 | in->in_brace_level->bl_remaining--; | | | |
1397 | debug_step("%d elements remaining", in->in_brace_level->bl_remaining); | | | |
1398 | | | | |
1399 | done_debug: | | | |
1400 | initialization_debug(in); | | | |
1401 | | | 1010 | |
1402 | done: | | | |
1403 | while (in->in_designation.dn_head != NULL) | | | |
1404 | designation_shift_level(&in->in_designation); | | | |
1405 | | | | |
1406 | debug_leave(); | | | |
1407 | } | | | |
1408 | | | 1011 | |
1409 | static struct initialization * | | 1012 | static struct initialization * |
1410 | current_init(void) | | 1013 | current_init(void) |
1411 | { | | 1014 | { |
1412 | | | 1015 | |
1413 | lint_assert(init != NULL); | | 1016 | lint_assert(init != NULL); |
1414 | return init; | | 1017 | return init; |
1415 | } | | 1018 | } |
1416 | | | 1019 | |
1417 | bool * | | | |
1418 | current_initerr(void) | | | |
1419 | { | | | |
1420 | | | | |
1421 | return ¤t_init()->in_err; | | | |
1422 | } | | | |
1423 | | | | |
1424 | sym_t ** | | 1020 | sym_t ** |
1425 | current_initsym(void) | | 1021 | current_initsym(void) |
1426 | { | | 1022 | { |
1427 | | | 1023 | |
1428 | return ¤t_init()->in_sym; | | 1024 | return ¤t_init()->in_sym; |
1429 | } | | 1025 | } |
1430 | | | 1026 | |
1431 | void | | 1027 | void |
1432 | begin_initialization(sym_t *sym) | | 1028 | begin_initialization(sym_t *sym) |
1433 | { | | 1029 | { |
1434 | struct initialization *in; | | 1030 | struct initialization *in; |
1435 | | | 1031 | |
1436 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); | | 1032 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); |
| | | 1033 | #ifdef DEBUG |
| | | 1034 | debug_indentation++; |
| | | 1035 | #endif |
| | | 1036 | |
1437 | in = initialization_new(sym); | | 1037 | in = initialization_new(sym); |
1438 | in->in_next = init; | | 1038 | in->in_enclosing = init; |
1439 | init = in; | | 1039 | init = in; |
1440 | } | | 1040 | } |
1441 | | | 1041 | |
1442 | void | | 1042 | void |
1443 | end_initialization(void) | | 1043 | end_initialization(void) |
1444 | { | | 1044 | { |
1445 | struct initialization *in; | | 1045 | struct initialization *in; |
1446 | | | 1046 | |
1447 | in = init; | | 1047 | in = init; |
1448 | init = init->in_next; | | 1048 | init = in->in_enclosing; |
1449 | initialization_free(in); | | 1049 | initialization_free(in); |
| | | 1050 | |
| | | 1051 | #ifdef DEBUG |
| | | 1052 | debug_indentation--; |
| | | 1053 | #endif |
1450 | debug_step("end initialization"); | | 1054 | debug_step("end initialization"); |
1451 | } | | 1055 | } |
1452 | | | 1056 | |
1453 | void | | 1057 | void |
1454 | add_designator_member(sbuf_t *sb) | | 1058 | add_designator_member(sbuf_t *sb) |
1455 | { | | 1059 | { |
1456 | | | 1060 | |
1457 | designation_add(¤t_init()->in_designation, | | 1061 | initialization_add_designator(current_init(), sb->sb_name, 0); |
1458 | designator_new(sb->sb_name)); | | | |
1459 | } | | 1062 | } |
1460 | | | 1063 | |
1461 | void | | 1064 | void |
1462 | add_designator_subscript(range_t range) | | 1065 | add_designator_subscript(range_t range) |
1463 | { | | 1066 | { |
1464 | | | 1067 | |
1465 | initialization_add_designator_subscript(current_init(), range); | | 1068 | initialization_add_designator(current_init(), NULL, range.hi); |
1466 | } | | | |
1467 | | | | |
1468 | void | | | |
1469 | initstack_init(void) | | | |
1470 | { | | | |
1471 | | | | |
1472 | initialization_init(current_init()); | | | |
1473 | } | | 1069 | } |
1474 | | | 1070 | |
1475 | void | | 1071 | void |
1476 | init_lbrace(void) | | 1072 | init_lbrace(void) |
1477 | { | | 1073 | { |
1478 | | | 1074 | |
1479 | initialization_lbrace(current_init()); | | 1075 | initialization_begin_brace_level(current_init()); |
1480 | } | | 1076 | } |
1481 | | | 1077 | |
1482 | void | | 1078 | void |
1483 | init_using_expr(tnode_t *tn) | | 1079 | init_expr(tnode_t *tn) |
1484 | { | | 1080 | { |
1485 | | | 1081 | |
1486 | initialization_expr(current_init(), tn); | | 1082 | initialization_expr(current_init(), tn); |
1487 | } | | 1083 | } |
1488 | | | 1084 | |
1489 | void | | 1085 | void |
1490 | init_rbrace(void) | | 1086 | init_rbrace(void) |
1491 | { | | 1087 | { |
1492 | | | 1088 | |
1493 | initialization_rbrace(current_init()); | | 1089 | initialization_end_brace_level(current_init()); |
1494 | } | | 1090 | } |