| @@ -1,1092 +1,1076 @@ | | | @@ -1,1092 +1,1076 @@ |
1 | /* $NetBSD: init.c,v 1.183 2021/03/30 16:07:07 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.184 2021/03/30 20:23:30 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | | 4 | * Copyright (c) 1994, 1995 Jochen Pohl |
5 | * Copyright (c) 2021 Roland Illig | | 5 | * Copyright (c) 2021 Roland Illig |
6 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
17 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
18 | * This product includes software developed by Jochen Pohl for | | 18 | * This product includes software developed by Jochen Pohl for |
19 | * The NetBSD Project. | | 19 | * The NetBSD Project. |
20 | * 4. The name of the author may not be used to endorse or promote products | | 20 | * 4. The name of the author may not be used to endorse or promote products |
21 | * derived from this software without specific prior written permission. | | 21 | * derived from this software without specific prior written permission. |
22 | * | | 22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
26 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 26 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
36 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(__RCSID) && !defined(lint) | | 40 | #if defined(__RCSID) && !defined(lint) |
41 | __RCSID("$NetBSD: init.c,v 1.183 2021/03/30 16:07:07 rillig Exp $"); | | 41 | __RCSID("$NetBSD: init.c,v 1.184 2021/03/30 20:23:30 rillig Exp $"); |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <stdlib.h> | | 44 | #include <stdlib.h> |
45 | #include <string.h> | | 45 | #include <string.h> |
46 | | | 46 | |
47 | #include "lint1.h" | | 47 | #include "lint1.h" |
48 | | | 48 | |
49 | | | 49 | |
50 | /* | | 50 | /* |
51 | * Initialization of global or local objects, like in: | | 51 | * Initialization of global or local objects, like in: |
52 | * | | 52 | * |
53 | * int number = 12345; | | 53 | * int number = 12345; |
54 | * int number_with_braces = { 12345 }; | | 54 | * int number_with_braces = { 12345 }; |
55 | * | | 55 | * |
56 | * int array_of_unknown_size[] = { 111, 222, 333 }; | | 56 | * int array_of_unknown_size[] = { 111, 222, 333 }; |
57 | * int array_flat[2][2] = { 11, 12, 21, 22 }; | | 57 | * int array_flat[2][2] = { 11, 12, 21, 22 }; |
58 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; | | 58 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; |
59 | * | | 59 | * |
60 | * struct { int x, y; } point = { 3, 4 }; | | 60 | * struct { int x, y; } point = { 3, 4 }; |
61 | * struct { int x, y; } point = { .y = 4, .x = 3 }; | | 61 | * struct { int x, y; } point = { .y = 4, .x = 3 }; |
62 | * | | 62 | * |
63 | * Any scalar expression in the initializer may be surrounded by arbitrarily | | 63 | * Any scalar expression in the initializer may be surrounded by arbitrarily |
64 | * 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 |
65 | * 6.7.8p11). | | 65 | * 6.7.8p11). |
66 | * | | 66 | * |
67 | * 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 |
68 | * array_flat or spelled out like in array_nested. This is unusual in | | 68 | * array_flat or spelled out like in array_nested. This is unusual in |
69 | * practice and therefore only supported very basically. | | 69 | * practice and therefore only supported very basically. |
70 | * | | 70 | * |
71 | * During initialization, 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_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 | * See also: | | 84 | * See also: |
85 | * C99 6.7.8 "Initialization" | | 85 | * C99 6.7.8 "Initialization" |
86 | * d_c99_init.c for more examples | | 86 | * d_c99_init.c for more examples |
87 | */ | | 87 | */ |
88 | | | 88 | |
89 | /* | | 89 | /* |
90 | * 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 |
91 | * initializer expression. Either a struct or union member, or an array | | 91 | * initializer expression. Either a struct or union member, or an array |
92 | * subscript. | | 92 | * subscript. |
93 | * | | 93 | * |
94 | * C99 6.7.8p6, 6.7.8p7 | | 94 | * C99 6.7.8p6, 6.7.8p7 |
95 | */ | | 95 | */ |
96 | struct designator { | | 96 | struct designator { |
97 | const char *dr_name; /* for struct and union */ | | 97 | const char *dr_name; /* for struct and union */ |
98 | size_t dr_subscript; /* for array */ | | 98 | size_t dr_subscript; /* for array */ |
99 | struct designator *dr_next; | | 99 | struct designator *dr_next; |
100 | }; | | 100 | }; |
101 | | | 101 | |
102 | /* | | 102 | /* |
103 | * The optional designation for an initializer, saying which sub-object to | | 103 | * The optional designation for an initializer, saying which sub-object to |
104 | * initialize. Examples for designations are '.member' or | | 104 | * initialize. Examples for designations are '.member' or |
105 | * '.member[123].member.member[1][1]'. | | 105 | * '.member[123].member.member[1][1]'. |
106 | * | | 106 | * |
107 | * C99 6.7.8p6, 6.7.8p7 | | 107 | * C99 6.7.8p6, 6.7.8p7 |
108 | */ | | 108 | */ |
109 | struct designation { | | 109 | struct designation { |
110 | struct designator *dn_head; | | 110 | struct designator *dn_head; |
111 | struct designator *dn_tail; | | 111 | struct designator *dn_tail; |
112 | }; | | 112 | }; |
113 | | | 113 | |
114 | /* | | 114 | /* |
115 | * Describes a single brace level of an ongoing initialization. | | 115 | * Describes a single brace level of an ongoing initialization. |
116 | * | | 116 | * |
117 | * See C99 6.7.8p17. | | 117 | * See C99 6.7.8p17. |
118 | */ | | 118 | */ |
119 | struct brace_level { | | 119 | struct brace_level { |
120 | /* | | 120 | /* |
121 | * The type of the current object that is initialized at this brace | | 121 | * The type of the current object that is initialized at this brace |
122 | * level. | | 122 | * level. |
123 | */ | | 123 | */ |
124 | const type_t *bl_type; | | 124 | const type_t *bl_type; |
125 | const sym_t *bl_next_member; /* for structs and unions */ | | 125 | const sym_t *bl_next_member; /* for structs and unions */ |
126 | size_t bl_array_next_subscript; | | 126 | size_t bl_array_next_subscript; |
127 | bool bl_array_of_unknown_size: 1; | | 127 | bool bl_array_of_unknown_size: 1; |
128 | bool bl_scalar_done: 1; /* for scalars */ | | 128 | bool bl_scalar_done: 1; /* for scalars */ |
129 | bool bl_omitted_braces: 1; /* skip further checks */ | | 129 | bool bl_omitted_braces: 1; /* skip further checks */ |
130 | struct designation bl_designation; /* .member[123].member */ | | 130 | struct designation bl_designation; /* .member[123].member */ |
131 | struct brace_level *bl_enclosing; | | 131 | struct brace_level *bl_enclosing; |
132 | }; | | 132 | }; |
133 | | | 133 | |
134 | struct initialization { | | 134 | struct initialization { |
135 | /* | | 135 | /* |
136 | * 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. |
137 | * The effect is that the rest of the initialization is ignored | | 137 | * The effect is that the rest of the initialization is ignored |
138 | * (parsed by yacc, expression trees built, but no initialization | | 138 | * (parsed by yacc, expression trees built, but no initialization |
139 | * takes place). | | 139 | * takes place). |
140 | */ | | 140 | */ |
141 | bool in_err; | | 141 | bool in_err; |
142 | | | 142 | |
143 | /* The symbol that is to be initialized. */ | | 143 | /* The symbol that is to be initialized. */ |
144 | sym_t *in_sym; | | 144 | sym_t *in_sym; |
145 | | | 145 | |
146 | /* The innermost brace level. */ | | 146 | /* The innermost brace level. */ |
147 | struct brace_level *in_brace_level; | | 147 | struct brace_level *in_brace_level; |
148 | | | 148 | |
149 | struct initialization *in_enclosing; | | 149 | struct initialization *in_enclosing; |
150 | }; | | 150 | }; |
151 | | | 151 | |
152 | | | 152 | |
153 | #ifdef DEBUG | | 153 | #ifdef DEBUG |
154 | static int debug_indentation = 0; | | 154 | static int debug_indentation = 0; |
155 | #endif | | 155 | #endif |
156 | | | 156 | |
157 | | | 157 | |
158 | #ifdef DEBUG | | 158 | #ifdef DEBUG |
159 | | | 159 | |
160 | static void __printflike(1, 2) | | 160 | static void __printflike(1, 2) |
161 | debug_printf(const char *fmt, ...) | | 161 | debug_printf(const char *fmt, ...) |
162 | { | | 162 | { |
163 | va_list va; | | 163 | va_list va; |
164 | | | 164 | |
165 | va_start(va, fmt); | | 165 | va_start(va, fmt); |
166 | vfprintf(stdout, fmt, va); | | 166 | vfprintf(stdout, fmt, va); |
167 | va_end(va); | | 167 | va_end(va); |
168 | } | | 168 | } |
169 | | | 169 | |
170 | static void | | 170 | static void |
171 | debug_indent(void) | | 171 | debug_indent(void) |
172 | { | | 172 | { |
173 | | | 173 | |
174 | debug_printf("%*s", 2 * debug_indentation, ""); | | 174 | debug_printf("%*s", 2 * debug_indentation, ""); |
175 | } | | 175 | } |
176 | | | 176 | |
177 | static void | | 177 | static void |
178 | debug_enter(const char *func) | | 178 | debug_enter(const char *func) |
179 | { | | 179 | { |
180 | | | 180 | |
181 | printf("%*s+ %s\n", 2 * debug_indentation++, "", func); | | 181 | printf("%*s+ %s\n", 2 * debug_indentation++, "", func); |
182 | } | | 182 | } |
183 | | | 183 | |
184 | static void __printflike(1, 2) | | 184 | static void __printflike(1, 2) |
185 | debug_step(const char *fmt, ...) | | 185 | debug_step(const char *fmt, ...) |
186 | { | | 186 | { |
187 | va_list va; | | 187 | va_list va; |
188 | | | 188 | |
189 | debug_indent(); | | 189 | debug_indent(); |
190 | va_start(va, fmt); | | 190 | va_start(va, fmt); |
191 | vfprintf(stdout, fmt, va); | | 191 | vfprintf(stdout, fmt, va); |
192 | va_end(va); | | 192 | va_end(va); |
193 | printf("\n"); | | 193 | printf("\n"); |
194 | } | | 194 | } |
195 | | | 195 | |
196 | static void | | 196 | static void |
197 | debug_leave(const char *func) | | 197 | debug_leave(const char *func) |
198 | { | | 198 | { |
199 | | | 199 | |
200 | printf("%*s- %s\n", 2 * --debug_indentation, "", func); | | 200 | printf("%*s- %s\n", 2 * --debug_indentation, "", func); |
201 | } | | 201 | } |
202 | | | 202 | |
203 | #define debug_enter() (debug_enter)(__func__) | | 203 | #define debug_enter() (debug_enter)(__func__) |
204 | #define debug_leave() (debug_leave)(__func__) | | 204 | #define debug_leave() (debug_leave)(__func__) |
205 | | | 205 | |
206 | #else | | 206 | #else |
207 | | | 207 | |
208 | /* TODO: This is C99 */ | | 208 | /* TODO: This is C99 */ |
209 | #define debug_printf(fmt, ...) do { } while (false) | | 209 | #define debug_printf(fmt, ...) do { } while (false) |
210 | #define debug_indent() do { } while (false) | | 210 | #define debug_indent() do { } while (false) |
211 | #define debug_enter() do { } while (false) | | 211 | #define debug_enter() do { } while (false) |
212 | #define debug_step(fmt, ...) do { } while (false) | | 212 | #define debug_step(fmt, ...) do { } while (false) |
213 | #define debug_leave() do { } while (false) | | 213 | #define debug_leave() do { } while (false) |
214 | | | 214 | |
215 | #endif | | 215 | #endif |
216 | | | 216 | |
217 | | | 217 | |
218 | static void * | | 218 | static void * |
219 | unconst_cast(const void *p) | | 219 | unconst_cast(const void *p) |
220 | { | | 220 | { |
221 | void *r; | | 221 | void *r; |
222 | | | 222 | |
223 | memcpy(&r, &p, sizeof r); | | 223 | memcpy(&r, &p, sizeof r); |
224 | return r; | | 224 | return r; |
225 | } | | 225 | } |
226 | | | 226 | |
227 | /* C99 6.7.8p7 */ | | 227 | /* C99 6.7.8p7 */ |
228 | static bool | | 228 | static bool |
229 | is_struct_or_union(tspec_t t) | | 229 | is_struct_or_union(tspec_t t) |
230 | { | | 230 | { |
231 | | | 231 | |
232 | return t == STRUCT || t == UNION; | | 232 | return t == STRUCT || t == UNION; |
233 | } | | 233 | } |
234 | | | 234 | |
235 | static bool | | 235 | static bool |
236 | has_automatic_storage_duration(const sym_t *sym) | | 236 | has_automatic_storage_duration(const sym_t *sym) |
237 | { | | 237 | { |
238 | | | 238 | |
239 | return sym->s_scl == AUTO || sym->s_scl == REG; | | 239 | return sym->s_scl == AUTO || sym->s_scl == REG; |
240 | } | | 240 | } |
241 | | | 241 | |
242 | /* C99 6.7.8p14, 6.7.8p15 */ | | 242 | /* C99 6.7.8p14, 6.7.8p15 */ |
243 | static bool | | 243 | static bool |
244 | is_string_array(const type_t *tp, tspec_t t) | | 244 | is_string_array(const type_t *tp, tspec_t t) |
245 | { | | 245 | { |
246 | tspec_t st; | | 246 | tspec_t st; |
247 | | | 247 | |
248 | if (tp == NULL || tp->t_tspec != ARRAY) | | 248 | if (tp == NULL || tp->t_tspec != ARRAY) |
249 | return false; | | 249 | return false; |
250 | | | 250 | |
251 | st = tp->t_subt->t_tspec; | | 251 | st = tp->t_subt->t_tspec; |
252 | return t == CHAR | | 252 | return t == CHAR |
253 | ? st == CHAR || st == UCHAR || st == SCHAR | | 253 | ? st == CHAR || st == UCHAR || st == SCHAR |
254 | : st == WCHAR; | | 254 | : st == WCHAR; |
255 | } | | 255 | } |
256 | | | 256 | |
257 | /* C99 6.7.8p9 */ | | 257 | /* C99 6.7.8p9 */ |
258 | static bool | | 258 | static bool |
259 | is_unnamed(const sym_t *m) | | 259 | is_unnamed(const sym_t *m) |
260 | { | | 260 | { |
261 | | | 261 | |
262 | return m->s_bitfield && m->s_name == unnamed; | | 262 | return m->s_bitfield && m->s_name == unnamed; |
263 | } | | 263 | } |
264 | | | 264 | |
265 | /* C99 6.7.8p9 */ | | 265 | /* C99 6.7.8p9 */ |
266 | static const sym_t * | | 266 | static const sym_t * |
267 | skip_unnamed(const sym_t *m) | | 267 | skip_unnamed(const sym_t *m) |
268 | { | | 268 | { |
269 | | | 269 | |
270 | while (m != NULL && is_unnamed(m)) | | 270 | while (m != NULL && is_unnamed(m)) |
271 | m = m->s_next; | | 271 | m = m->s_next; |
272 | return m; | | 272 | return m; |
273 | } | | 273 | } |
274 | | | 274 | |
275 | static const sym_t * | | 275 | static const sym_t * |
276 | first_named_member(const type_t *tp) | | 276 | first_named_member(const type_t *tp) |
277 | { | | 277 | { |
278 | | | 278 | |
279 | lint_assert(is_struct_or_union(tp->t_tspec)); | | 279 | lint_assert(is_struct_or_union(tp->t_tspec)); |
280 | return skip_unnamed(tp->t_str->sou_first_member); | | 280 | return skip_unnamed(tp->t_str->sou_first_member); |
281 | } | | 281 | } |
282 | | | 282 | |
283 | static const sym_t * | | 283 | static const sym_t * |
284 | look_up_member(const type_t *tp, const char *name) | | 284 | look_up_member(const type_t *tp, const char *name) |
285 | { | | 285 | { |
286 | const sym_t *m; | | 286 | const sym_t *m; |
287 | | | 287 | |
288 | lint_assert(is_struct_or_union(tp->t_tspec)); | | 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) | | 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) | | 290 | if (!is_unnamed(m) && strcmp(m->s_name, name) == 0) |
291 | return m; | | 291 | return m; |
292 | return NULL; | | 292 | return NULL; |
293 | } | | 293 | } |
294 | | | 294 | |
295 | static const type_t * | | 295 | static const type_t * |
296 | sym_type(const sym_t *sym) | | 296 | sym_type(const sym_t *sym) |
297 | { | | 297 | { |
298 | | | 298 | |
299 | return sym != NULL ? sym->s_type : NULL; | | 299 | return sym != NULL ? sym->s_type : NULL; |
300 | } | | 300 | } |
301 | | | 301 | |
302 | static const type_t * | | 302 | static const type_t * |
303 | look_up_member_type(const type_t *tp, const char *name) | | 303 | look_up_member_type(const type_t *tp, const char *name) |
304 | { | | 304 | { |
305 | const sym_t *member; | | 305 | const sym_t *member; |
306 | | | 306 | |
307 | member = look_up_member(tp, name); | | 307 | member = look_up_member(tp, name); |
308 | if (member == NULL) { | | 308 | if (member == NULL) { |
309 | /* type '%s' does not have member '%s' */ | | 309 | /* type '%s' does not have member '%s' */ |
310 | error(101, type_name(tp), name); | | 310 | error(101, type_name(tp), name); |
311 | } | | 311 | } |
312 | | | 312 | |
313 | return sym_type(member); | | 313 | return sym_type(member); |
314 | } | | 314 | } |
315 | | | 315 | |
316 | static void | | 316 | static void |
317 | update_type_of_array_of_unknown_size(sym_t *sym, size_t size) | | 317 | update_type_of_array_of_unknown_size(sym_t *sym, size_t size) |
318 | { | | 318 | { |
319 | type_t *tp; | | 319 | type_t *tp; |
320 | | | 320 | |
321 | tp = duptyp(sym->s_type); | | 321 | tp = duptyp(sym->s_type); |
322 | tp->t_dim = (int)size; | | 322 | tp->t_dim = (int)size; |
323 | tp->t_incomplete_array = false; | | 323 | tp->t_incomplete_array = false; |
324 | sym->s_type = tp; | | 324 | sym->s_type = tp; |
325 | } | | 325 | } |
326 | | | 326 | |
327 | | | 327 | |
328 | /* In traditional C, bit-fields can be initialized only by integer constants. */ | | 328 | /* In traditional C, bit-fields can be initialized only by integer constants. */ |
329 | static void | | 329 | static void |
330 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) | | 330 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) |
331 | { | | 331 | { |
332 | | | 332 | |
333 | if (tflag && | | 333 | if (tflag && |
334 | is_integer(lt) && | | 334 | is_integer(lt) && |
335 | ln->tn_type->t_bitfield && | | 335 | ln->tn_type->t_bitfield && |
336 | !is_integer(rt)) { | | 336 | !is_integer(rt)) { |
337 | /* bit-field initialization is illegal in traditional C */ | | 337 | /* bit-field initialization is illegal in traditional C */ |
338 | warning(186); | | 338 | warning(186); |
339 | } | | 339 | } |
340 | } | | 340 | } |
341 | | | 341 | |
342 | static void | | 342 | static void |
343 | check_non_constant_initializer(const tnode_t *tn, const sym_t *sym) | | 343 | check_non_constant_initializer(const tnode_t *tn, const sym_t *sym) |
344 | { | | 344 | { |
345 | const sym_t *unused_sym; | | 345 | const sym_t *unused_sym; |
346 | ptrdiff_t unused_offs; | | 346 | ptrdiff_t unused_offs; |
347 | | | 347 | |
348 | if (tn == NULL || tn->tn_op == CON) | | 348 | if (tn == NULL || tn->tn_op == CON) |
349 | return; | | 349 | return; |
350 | | | 350 | |
351 | if (constant_addr(tn, &unused_sym, &unused_offs)) | | 351 | if (constant_addr(tn, &unused_sym, &unused_offs)) |
352 | return; | | 352 | return; |
353 | | | 353 | |
354 | if (has_automatic_storage_duration(sym)) { | | 354 | if (has_automatic_storage_duration(sym)) { |
355 | /* non-constant initializer */ | | 355 | /* non-constant initializer */ |
356 | c99ism(177); | | 356 | c99ism(177); |
357 | } else { | | 357 | } else { |
358 | /* non-constant initializer */ | | 358 | /* non-constant initializer */ |
359 | error(177); | | 359 | error(177); |
360 | } | | 360 | } |
361 | } | | 361 | } |
362 | | | 362 | |
363 | static void | | 363 | static void |
364 | check_no_auto_aggregate(const sym_t *sym) | | 364 | check_no_auto_aggregate(const sym_t *sym) |
365 | { | | 365 | { |
366 | | | 366 | |
367 | if (tflag && | | 367 | if (tflag && |
368 | has_automatic_storage_duration(sym) && | | 368 | has_automatic_storage_duration(sym) && |
369 | !is_scalar(sym->s_type->t_tspec)) { | | 369 | !is_scalar(sym->s_type->t_tspec)) { |
370 | /* no automatic aggregate initialization in trad. C */ | | 370 | /* no automatic aggregate initialization in trad. C */ |
371 | warning(188); | | 371 | warning(188); |
372 | } | | 372 | } |
373 | } | | 373 | } |
374 | | | 374 | |
375 | static void | | 375 | static void |
376 | check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn) | | 376 | check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn) |
377 | { | | 377 | { |
378 | tnode_t *ln; | | 378 | tnode_t *ln; |
379 | tspec_t lt, rt; | | 379 | tspec_t lt, rt; |
380 | struct mbl *tmem; | | 380 | struct mbl *tmem; |
381 | | | 381 | |
382 | /* Create a temporary node for the left side. */ | | 382 | /* Create a temporary node for the left side. */ |
383 | ln = tgetblk(sizeof *ln); | | 383 | ln = tgetblk(sizeof *ln); |
384 | ln->tn_op = NAME; | | 384 | ln->tn_op = NAME; |
385 | ln->tn_type = tduptyp(tp); | | 385 | ln->tn_type = tduptyp(tp); |
386 | ln->tn_type->t_const = false; | | 386 | ln->tn_type->t_const = false; |
387 | ln->tn_lvalue = true; | | 387 | ln->tn_lvalue = true; |
388 | ln->tn_sym = sym; | | 388 | ln->tn_sym = sym; |
389 | | | 389 | |
390 | tn = cconv(tn); | | 390 | tn = cconv(tn); |
391 | | | 391 | |
392 | lt = ln->tn_type->t_tspec; | | 392 | lt = ln->tn_type->t_tspec; |
393 | rt = tn->tn_type->t_tspec; | | 393 | rt = tn->tn_type->t_tspec; |
394 | | | 394 | |
395 | debug_step("typeok '%s', '%s'", | | 395 | debug_step("typeok '%s', '%s'", |
396 | type_name(ln->tn_type), type_name(tn->tn_type)); | | 396 | type_name(ln->tn_type), type_name(tn->tn_type)); |
397 | if (!typeok(INIT, 0, ln, tn)) | | 397 | if (!typeok(INIT, 0, ln, tn)) |
398 | return; | | 398 | return; |
399 | | | 399 | |
400 | /* | | 400 | /* |
401 | * Preserve the tree memory. This is necessary because otherwise | | 401 | * Preserve the tree memory. This is necessary because otherwise |
402 | * expr() would free it. | | 402 | * expr() would free it. |
403 | */ | | 403 | */ |
404 | tmem = tsave(); | | 404 | tmem = tsave(); |
405 | expr(tn, true, false, true, false); | | 405 | expr(tn, true, false, true, false); |
406 | trestor(tmem); | | 406 | trestor(tmem); |
407 | | | 407 | |
408 | check_bit_field_init(ln, lt, rt); | | 408 | check_bit_field_init(ln, lt, rt); |
409 | | | 409 | |
410 | /* | | 410 | /* |
411 | * XXX: Is it correct to do this conversion _after_ the typeok above? | | 411 | * XXX: Is it correct to do this conversion _after_ the typeok above? |
412 | */ | | 412 | */ |
413 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) | | 413 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) |
414 | tn = convert(INIT, 0, unconst_cast(tp), tn); | | 414 | tn = convert(INIT, 0, unconst_cast(tp), tn); |
415 | | | 415 | |
416 | check_non_constant_initializer(tn, sym); | | 416 | check_non_constant_initializer(tn, sym); |
417 | } | | 417 | } |
418 | | | 418 | |
419 | | | 419 | |
420 | static struct designator * | | 420 | static struct designator * |
421 | designator_new(const char *name, size_t subscript) | | 421 | designator_new(const char *name, size_t subscript) |
422 | { | | 422 | { |
423 | struct designator *dr; | | 423 | struct designator *dr; |
424 | | | 424 | |
425 | dr = xcalloc(1, sizeof *dr); | | 425 | dr = xcalloc(1, sizeof *dr); |
426 | dr->dr_name = name; | | 426 | dr->dr_name = name; |
427 | dr->dr_subscript = subscript; | | 427 | dr->dr_subscript = subscript; |
428 | return dr; | | 428 | return dr; |
429 | } | | 429 | } |
430 | | | 430 | |
431 | static void | | 431 | static void |
432 | designator_free(struct designator *dr) | | 432 | designator_free(struct designator *dr) |
433 | { | | 433 | { |
434 | | | 434 | |
435 | free(dr); | | 435 | free(dr); |
436 | } | | 436 | } |
437 | | | 437 | |
438 | | | 438 | |
439 | static const type_t * | | 439 | static const type_t * |
440 | designator_look_up(const struct designator *dr, const type_t *tp) | | 440 | designator_look_up(const struct designator *dr, const type_t *tp) |
441 | { | | 441 | { |
442 | switch (tp->t_tspec) { | | 442 | switch (tp->t_tspec) { |
443 | case STRUCT: | | 443 | case STRUCT: |
444 | case UNION: | | 444 | case UNION: |
445 | if (dr->dr_name == NULL) { | | 445 | if (dr->dr_name == NULL) { |
446 | /* syntax error '%s' */ | | 446 | /* syntax error '%s' */ |
447 | error(249, "designator '[...]' is only for arrays"); | | 447 | error(249, "designator '[...]' is only for arrays"); |
448 | return sym_type(first_named_member(tp)); | | 448 | return sym_type(first_named_member(tp)); |
449 | } | | 449 | } |
450 | | | 450 | |
451 | return look_up_member_type(tp, dr->dr_name); | | 451 | return look_up_member_type(tp, dr->dr_name); |
452 | case ARRAY: | | 452 | case ARRAY: |
453 | if (dr->dr_name != NULL) { | | 453 | if (dr->dr_name != NULL) { |
454 | /* syntax error '%s' */ | | 454 | /* syntax error '%s' */ |
455 | error(249, | | 455 | error(249, |
456 | "designator '.member' is only for struct/union"); | | 456 | "designator '.member' is only for struct/union"); |
457 | } | | 457 | } |
458 | if (!tp->t_incomplete_array && | | 458 | if (!tp->t_incomplete_array && |
459 | dr->dr_subscript >= (size_t)tp->t_dim) { | | 459 | dr->dr_subscript >= (size_t)tp->t_dim) { |
460 | /* array subscript cannot be > %d: %ld */ | | 460 | /* array subscript cannot be > %d: %ld */ |
461 | error(168, tp->t_dim - 1, (long)dr->dr_subscript); | | 461 | error(168, tp->t_dim - 1, (long)dr->dr_subscript); |
462 | } | | 462 | } |
463 | return tp->t_subt; | | 463 | return tp->t_subt; |
464 | default: | | 464 | default: |
465 | /* syntax error '%s' */ | | 465 | /* syntax error '%s' */ |
466 | error(249, "scalar type cannot use designator"); | | 466 | error(249, "scalar type cannot use designator"); |
467 | return tp; | | 467 | return tp; |
468 | } | | 468 | } |
469 | } | | 469 | } |
470 | | | 470 | |
471 | | | 471 | |
472 | #ifdef DEBUG | | 472 | #ifdef DEBUG |
473 | static void | | 473 | static void |
474 | designation_debug(const struct designation *dn) | | 474 | designation_debug(const struct designation *dn) |
475 | { | | 475 | { |
476 | const struct designator *dr; | | 476 | const struct designator *dr; |
477 | | | 477 | |
478 | if (dn->dn_head == NULL) | | 478 | if (dn->dn_head == NULL) |
479 | return; | | 479 | return; |
480 | | | 480 | |
481 | debug_indent(); | | 481 | debug_indent(); |
482 | debug_printf("designation: "); | | 482 | debug_printf("designation: "); |
483 | for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) { | | 483 | for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) { |
484 | if (dr->dr_name != NULL) { | | 484 | if (dr->dr_name != NULL) { |
485 | debug_printf(".%s", dr->dr_name); | | 485 | debug_printf(".%s", dr->dr_name); |
486 | lint_assert(dr->dr_subscript == 0); | | 486 | lint_assert(dr->dr_subscript == 0); |
487 | } else | | 487 | } else |
488 | debug_printf("[%zu]", dr->dr_subscript); | | 488 | debug_printf("[%zu]", dr->dr_subscript); |
489 | } | | 489 | } |
490 | debug_printf("\n"); | | 490 | debug_printf("\n"); |
491 | } | | 491 | } |
492 | #else | | 492 | #else |
493 | #define designation_debug(dn) do { } while (false) | | 493 | #define designation_debug(dn) do { } while (false) |
494 | #endif | | 494 | #endif |
495 | | | 495 | |
496 | static void | | 496 | static void |
497 | designation_add(struct designation *dn, const char *name, size_t subscript) | | 497 | designation_add(struct designation *dn, const char *name, size_t subscript) |
498 | { | | 498 | { |
499 | struct designator *dr; | | 499 | struct designator *dr; |
500 | | | 500 | |
501 | dr = designator_new(name, subscript); | | 501 | dr = designator_new(name, subscript); |
502 | | | 502 | |
503 | if (dn->dn_head != NULL) { | | 503 | if (dn->dn_head != NULL) { |
504 | dn->dn_tail->dr_next = dr; | | 504 | dn->dn_tail->dr_next = dr; |
505 | dn->dn_tail = dr; | | 505 | dn->dn_tail = dr; |
506 | } else { | | 506 | } else { |
507 | dn->dn_head = dr; | | 507 | dn->dn_head = dr; |
508 | dn->dn_tail = dr; | | 508 | dn->dn_tail = dr; |
509 | } | | 509 | } |
510 | } | | 510 | } |
511 | | | 511 | |
512 | /* | | 512 | /* |
513 | * Starting at the type of the current object, resolve the type of the | | 513 | * Starting at the type of the current object, resolve the type of the |
514 | * sub-object by following each designator in the list. | | 514 | * sub-object by following each designator in the list. |
515 | */ | | 515 | */ |
516 | static const type_t * | | 516 | static const type_t * |
517 | designation_look_up(const struct designation *dn, const type_t *tp) | | 517 | designation_look_up(const struct designation *dn, const type_t *tp) |
518 | { | | 518 | { |
519 | const struct designator *dr; | | 519 | const struct designator *dr; |
520 | | | 520 | |
521 | for (dr = dn->dn_head; dr != NULL && tp != NULL; dr = dr->dr_next) | | 521 | for (dr = dn->dn_head; dr != NULL && tp != NULL; dr = dr->dr_next) |
522 | tp = designator_look_up(dr, tp); | | 522 | tp = designator_look_up(dr, tp); |
523 | return tp; | | 523 | return tp; |
524 | } | | 524 | } |
525 | | | 525 | |
526 | | | 526 | |
527 | | | 527 | |
528 | static void | | 528 | static void |
529 | designation_reset(struct designation *dn) | | 529 | designation_reset(struct designation *dn) |
530 | { | | 530 | { |
531 | struct designator *dr, *next; | | 531 | struct designator *dr, *next; |
532 | | | 532 | |
533 | for (dr = dn->dn_head; dr != NULL; dr = next) { | | 533 | for (dr = dn->dn_head; dr != NULL; dr = next) { |
534 | next = dr->dr_next; | | 534 | next = dr->dr_next; |
535 | designator_free(dr); | | 535 | designator_free(dr); |
536 | } | | 536 | } |
| | | 537 | |
| | | 538 | dn->dn_head = NULL; |
| | | 539 | dn->dn_tail = NULL; |
537 | } | | 540 | } |
538 | | | 541 | |
539 | | | 542 | |
540 | static struct brace_level * | | 543 | static struct brace_level * |
541 | brace_level_new(const type_t *tp, struct brace_level *enclosing) | | 544 | brace_level_new(const type_t *tp, struct brace_level *enclosing) |
542 | { | | 545 | { |
543 | struct brace_level *bl; | | 546 | struct brace_level *bl; |
544 | | | 547 | |
545 | bl = xcalloc(1, sizeof(*bl)); | | 548 | bl = xcalloc(1, sizeof(*bl)); |
546 | bl->bl_type = tp; | | 549 | bl->bl_type = tp; |
547 | bl->bl_enclosing = enclosing; | | 550 | bl->bl_enclosing = enclosing; |
548 | if (is_struct_or_union(tp->t_tspec)) | | 551 | if (is_struct_or_union(tp->t_tspec)) |
549 | bl->bl_next_member = first_named_member(tp); | | 552 | bl->bl_next_member = first_named_member(tp); |
550 | | | 553 | |
551 | return bl; | | 554 | return bl; |
552 | } | | 555 | } |
553 | | | 556 | |
554 | static void | | 557 | static void |
555 | brace_level_free(struct brace_level *bl) | | 558 | brace_level_free(struct brace_level *bl) |
556 | { | | 559 | { |
557 | | | 560 | |
558 | designation_reset(&bl->bl_designation); | | 561 | designation_reset(&bl->bl_designation); |
559 | free(bl); | | 562 | free(bl); |
560 | } | | 563 | } |
561 | | | 564 | |
562 | #ifdef DEBUG | | 565 | #ifdef DEBUG |
563 | static void | | 566 | static void |
564 | brace_level_debug(const struct brace_level *bl) | | 567 | brace_level_debug(const struct brace_level *bl) |
565 | { | | 568 | { |
566 | | | 569 | |
567 | lint_assert(bl->bl_type != NULL); | | 570 | lint_assert(bl->bl_type != NULL); |
568 | lint_assert(bl->bl_next_member == NULL || | | 571 | lint_assert(bl->bl_next_member == NULL || |
569 | !is_unnamed(bl->bl_next_member)); | | 572 | !is_unnamed(bl->bl_next_member)); |
570 | | | 573 | |
571 | debug_printf("type '%s'", type_name(bl->bl_type)); | | 574 | debug_printf("type '%s'", type_name(bl->bl_type)); |
572 | | | 575 | |
573 | if (bl->bl_array_of_unknown_size) | | 576 | if (bl->bl_array_of_unknown_size) |
574 | debug_printf(", array of unknown size"); | | 577 | debug_printf(", array of unknown size"); |
575 | | | 578 | |
576 | if (is_struct_or_union(bl->bl_type->t_tspec) && | | 579 | if (is_struct_or_union(bl->bl_type->t_tspec) && |
577 | bl->bl_next_member != NULL) | | 580 | bl->bl_next_member != NULL) |
578 | debug_printf(", next member '%s'", | | 581 | debug_printf(", next member '%s'", |
579 | bl->bl_next_member->s_name); | | 582 | bl->bl_next_member->s_name); |
580 | if (bl->bl_type->t_tspec == ARRAY) | | 583 | if (bl->bl_type->t_tspec == ARRAY) |
581 | debug_printf(", next array subscript %zu", | | 584 | debug_printf(", next array subscript %zu", |
582 | bl->bl_array_next_subscript); | | 585 | bl->bl_array_next_subscript); |
583 | | | 586 | |
584 | debug_printf("\n"); | | 587 | debug_printf("\n"); |
585 | } | | 588 | } |
586 | #else | | 589 | #else |
587 | #define brace_level_debug(level) do { } while (false) | | 590 | #define brace_level_debug(level) do { } while (false) |
588 | #endif | | 591 | #endif |
589 | | | 592 | |
590 | static void | | | |
591 | brace_level_remove_designation(struct brace_level *bl) | | | |
592 | { | | | |
593 | struct designator *dr, *next; | | | |
594 | | | | |
595 | for (dr = bl->bl_designation.dn_head; dr != NULL; dr = next) { | | | |
596 | next = dr->dr_next; | | | |
597 | designator_free(dr); | | | |
598 | } | | | |
599 | | | | |
600 | bl->bl_designation.dn_head = NULL; | | | |
601 | bl->bl_designation.dn_tail = NULL; | | | |
602 | } | | | |
603 | | | | |
604 | | | | |
605 | static const type_t * | | 593 | static const type_t * |
606 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) | | 594 | brace_level_sub_type_struct_or_union(const struct brace_level *bl) |
607 | { | | 595 | { |
608 | | | 596 | |
609 | if (bl->bl_next_member == NULL) { | | 597 | if (bl->bl_next_member == NULL) { |
610 | /* too many struct/union initializers */ | | 598 | /* too many struct/union initializers */ |
611 | error(172); | | 599 | error(172); |
612 | return NULL; | | 600 | return NULL; |
613 | } | | 601 | } |
614 | | | 602 | |
615 | lint_assert(!is_unnamed(bl->bl_next_member)); | | 603 | lint_assert(!is_unnamed(bl->bl_next_member)); |
616 | return sym_type(bl->bl_next_member); | | 604 | return sym_type(bl->bl_next_member); |
617 | } | | 605 | } |
618 | | | 606 | |
619 | static const type_t * | | 607 | static const type_t * |
620 | brace_level_sub_type_array(const struct brace_level *bl) | | 608 | brace_level_sub_type_array(const struct brace_level *bl) |
621 | { | | 609 | { |
622 | | | 610 | |
623 | if (!bl->bl_type->t_incomplete_array && | | 611 | if (!bl->bl_type->t_incomplete_array && |
624 | !bl->bl_omitted_braces && | | 612 | !bl->bl_omitted_braces && |
625 | bl->bl_array_next_subscript >= (size_t)bl->bl_type->t_dim) { | | 613 | bl->bl_array_next_subscript >= (size_t)bl->bl_type->t_dim) { |
626 | /* too many array initializers, expected %d */ | | 614 | /* too many array initializers, expected %d */ |
627 | error(173, bl->bl_type->t_dim); | | 615 | error(173, bl->bl_type->t_dim); |
628 | } | | 616 | } |
629 | | | 617 | |
630 | return bl->bl_type->t_subt; | | 618 | return bl->bl_type->t_subt; |
631 | } | | 619 | } |
632 | | | 620 | |
633 | static const type_t * | | 621 | static const type_t * |
634 | brace_level_sub_type_scalar(const struct brace_level *bl) | | 622 | brace_level_sub_type_scalar(const struct brace_level *bl) |
635 | { | | 623 | { |
636 | | | 624 | |
637 | if (bl->bl_scalar_done) { | | 625 | if (bl->bl_scalar_done) { |
638 | /* too many initializers */ | | 626 | /* too many initializers */ |
639 | error(174); | | 627 | error(174); |
640 | } | | 628 | } |
641 | | | 629 | |
642 | return bl->bl_type; | | 630 | return bl->bl_type; |
643 | } | | 631 | } |
644 | | | 632 | |
645 | /* Return the type of the sub-object that is currently being initialized. */ | | 633 | /* Return the type of the sub-object that is currently being initialized. */ |
646 | static const type_t * | | 634 | static const type_t * |
647 | brace_level_sub_type(const struct brace_level *bl) | | 635 | brace_level_sub_type(const struct brace_level *bl) |
648 | { | | 636 | { |
649 | | | 637 | |
650 | if (bl->bl_designation.dn_head != NULL) | | 638 | if (bl->bl_designation.dn_head != NULL) |
651 | return designation_look_up(&bl->bl_designation, bl->bl_type); | | 639 | return designation_look_up(&bl->bl_designation, bl->bl_type); |
652 | | | 640 | |
653 | switch (bl->bl_type->t_tspec) { | | 641 | switch (bl->bl_type->t_tspec) { |
654 | case STRUCT: | | 642 | case STRUCT: |
655 | case UNION: | | 643 | case UNION: |
656 | return brace_level_sub_type_struct_or_union(bl); | | 644 | return brace_level_sub_type_struct_or_union(bl); |
657 | case ARRAY: | | 645 | case ARRAY: |
658 | return brace_level_sub_type_array(bl); | | 646 | return brace_level_sub_type_array(bl); |
659 | default: | | 647 | default: |
660 | return brace_level_sub_type_scalar(bl); | | 648 | return brace_level_sub_type_scalar(bl); |
661 | } | | 649 | } |
662 | } | | 650 | } |
663 | | | 651 | |
664 | static void | | 652 | static void |
665 | brace_level_apply_designation(struct brace_level *bl) | | 653 | brace_level_apply_designation(struct brace_level *bl) |
666 | { | | 654 | { |
667 | const struct designator *dr = bl->bl_designation.dn_head; | | 655 | const struct designator *dr = bl->bl_designation.dn_head; |
668 | | | 656 | |
669 | if (dr == NULL) | | 657 | if (dr == NULL) |
670 | return; | | 658 | return; |
671 | | | 659 | |
672 | designation_debug(&bl->bl_designation); | | 660 | designation_debug(&bl->bl_designation); |
673 | | | 661 | |
674 | switch (bl->bl_type->t_tspec) { | | 662 | switch (bl->bl_type->t_tspec) { |
675 | case STRUCT: | | 663 | case STRUCT: |
676 | case UNION: | | 664 | case UNION: |
677 | if (dr->dr_name == NULL) | | 665 | if (dr->dr_name == NULL) |
678 | return; /* error, silently ignored */ | | 666 | return; /* error, silently ignored */ |
679 | bl->bl_next_member = look_up_member(bl->bl_type, dr->dr_name); | | 667 | bl->bl_next_member = look_up_member(bl->bl_type, dr->dr_name); |
680 | break; | | 668 | break; |
681 | case ARRAY: | | 669 | case ARRAY: |
682 | if (dr->dr_name != NULL) | | 670 | if (dr->dr_name != NULL) |
683 | return; /* error, silently ignored */ | | 671 | return; /* error, silently ignored */ |
684 | bl->bl_array_next_subscript = dr->dr_subscript; | | 672 | bl->bl_array_next_subscript = dr->dr_subscript; |
685 | break; | | 673 | break; |
686 | default: | | 674 | default: |
687 | break; /* error, silently ignored */ | | 675 | break; /* error, silently ignored */ |
688 | } | | 676 | } |
689 | } | | 677 | } |
690 | | | 678 | |
691 | /* | | 679 | /* |
692 | * After initializing a sub-object, advance to the next sub-object. | | 680 | * After initializing a sub-object, advance to the next sub-object. |
693 | * | | 681 | * |
694 | * C99 6.7.8p17 | | 682 | * C99 6.7.8p17 |
695 | */ | | 683 | */ |
696 | static void | | 684 | static void |
697 | brace_level_advance(struct brace_level *bl) | | 685 | brace_level_advance(struct brace_level *bl) |
698 | { | | 686 | { |
699 | | | 687 | |
700 | switch (bl->bl_type->t_tspec) { | | 688 | switch (bl->bl_type->t_tspec) { |
701 | case STRUCT: | | 689 | case STRUCT: |
702 | lint_assert(bl->bl_next_member != NULL); | | 690 | lint_assert(bl->bl_next_member != NULL); |
703 | bl->bl_next_member = skip_unnamed(bl->bl_next_member->s_next); | | 691 | bl->bl_next_member = skip_unnamed(bl->bl_next_member->s_next); |
704 | break; | | 692 | break; |
705 | case UNION: | | 693 | case UNION: |
706 | bl->bl_next_member = NULL; | | 694 | bl->bl_next_member = NULL; |
707 | break; | | 695 | break; |
708 | case ARRAY: | | 696 | case ARRAY: |
709 | bl->bl_array_next_subscript++; | | 697 | bl->bl_array_next_subscript++; |
710 | break; | | 698 | break; |
711 | default: | | 699 | default: |
712 | bl->bl_scalar_done = true; | | 700 | bl->bl_scalar_done = true; |
713 | break; | | 701 | break; |
714 | } | | 702 | } |
715 | } | | 703 | } |
716 | | | 704 | |
717 | | | 705 | |
718 | static struct initialization * | | 706 | static struct initialization * |
719 | initialization_new(sym_t *sym) | | 707 | initialization_new(sym_t *sym) |
720 | { | | 708 | { |
721 | struct initialization *in; | | 709 | struct initialization *in; |
722 | | | 710 | |
723 | in = xcalloc(1, sizeof(*in)); | | 711 | in = xcalloc(1, sizeof(*in)); |
724 | in->in_sym = sym; | | 712 | in->in_sym = sym; |
725 | | | 713 | |
726 | return in; | | 714 | return in; |
727 | } | | 715 | } |
728 | | | 716 | |
729 | static void | | 717 | static void |
730 | initialization_free(struct initialization *in) | | 718 | initialization_free(struct initialization *in) |
731 | { | | 719 | { |
732 | struct brace_level *bl, *next; | | 720 | struct brace_level *bl, *next; |
733 | | | 721 | |
734 | for (bl = in->in_brace_level; bl != NULL; bl = next) { | | 722 | for (bl = in->in_brace_level; bl != NULL; bl = next) { |
735 | next = bl->bl_enclosing; | | 723 | next = bl->bl_enclosing; |
736 | brace_level_free(bl); | | 724 | brace_level_free(bl); |
737 | } | | 725 | } |
738 | | | 726 | |
739 | free(in); | | 727 | free(in); |
740 | } | | 728 | } |
741 | | | 729 | |
742 | #ifdef DEBUG | | 730 | #ifdef DEBUG |
743 | static void | | 731 | static void |
744 | initialization_debug(const struct initialization *in) | | 732 | initialization_debug(const struct initialization *in) |
745 | { | | 733 | { |
746 | size_t i; | | 734 | size_t i; |
747 | const struct brace_level *bl; | | 735 | const struct brace_level *bl; |
748 | | | 736 | |
749 | if (in->in_brace_level == NULL) { | | 737 | if (in->in_brace_level == NULL) { |
750 | debug_step("no brace level"); | | 738 | debug_step("no brace level"); |
751 | return; | | 739 | return; |
752 | } | | 740 | } |
753 | | | 741 | |
754 | i = 0; | | 742 | i = 0; |
755 | for (bl = in->in_brace_level; bl != NULL; bl = bl->bl_enclosing) { | | 743 | for (bl = in->in_brace_level; bl != NULL; bl = bl->bl_enclosing) { |
756 | debug_indent(); | | 744 | debug_indent(); |
757 | debug_printf("brace level %zu: ", i); | | 745 | debug_printf("brace level %zu: ", i); |
758 | brace_level_debug(bl); | | 746 | brace_level_debug(bl); |
759 | i++; | | 747 | i++; |
760 | } | | 748 | } |
761 | } | | 749 | } |
762 | #else | | 750 | #else |
763 | #define initialization_debug(in) do { } while (false) | | 751 | #define initialization_debug(in) do { } while (false) |
764 | #endif | | 752 | #endif |
765 | | | 753 | |
766 | /* | | 754 | /* |
767 | * Return the type of the object or sub-object that is currently being | | 755 | * Return the type of the object or sub-object that is currently being |
768 | * initialized. | | 756 | * initialized. |
769 | */ | | 757 | */ |
770 | static const type_t * | | 758 | static const type_t * |
771 | initialization_sub_type(struct initialization *in) | | 759 | initialization_sub_type(struct initialization *in) |
772 | { | | 760 | { |
773 | const type_t *tp; | | 761 | const type_t *tp; |
774 | | | 762 | |
775 | tp = in->in_brace_level != NULL | | 763 | tp = in->in_brace_level != NULL |
776 | ? brace_level_sub_type(in->in_brace_level) | | 764 | ? brace_level_sub_type(in->in_brace_level) |
777 | : in->in_sym->s_type; | | 765 | : in->in_sym->s_type; |
778 | if (tp == NULL) | | 766 | if (tp == NULL) |
779 | in->in_err = true; | | 767 | in->in_err = true; |
780 | return tp; | | 768 | return tp; |
781 | } | | 769 | } |
782 | | | 770 | |
783 | static void | | 771 | static void |
784 | initialization_begin_brace_level(struct initialization *in) | | 772 | initialization_begin_brace_level(struct initialization *in) |
785 | { | | 773 | { |
786 | const type_t *tp; | | 774 | const type_t *tp; |
787 | | | 775 | |
788 | if (in->in_err) | | 776 | if (in->in_err) |
789 | return; | | 777 | return; |
790 | | | 778 | |
791 | debug_enter(); | | 779 | debug_enter(); |
792 | | | 780 | |
793 | tp = initialization_sub_type(in); | | 781 | tp = initialization_sub_type(in); |
794 | if (tp == NULL) { | | 782 | if (tp == NULL) { |
795 | in->in_err = true; | | 783 | in->in_err = true; |
796 | goto done; | | 784 | goto done; |
797 | } | | 785 | } |
798 | | | 786 | |
799 | if (tflag && in->in_brace_level == NULL) | | 787 | if (tflag && in->in_brace_level == NULL) |
800 | check_no_auto_aggregate(in->in_sym); | | 788 | check_no_auto_aggregate(in->in_sym); |
801 | | | 789 | |
802 | if (tflag && tp->t_tspec == UNION) { | | 790 | if (tflag && tp->t_tspec == UNION) { |
803 | /* initialization of union is illegal in traditional C */ | | 791 | /* initialization of union is illegal in traditional C */ |
804 | warning(238); | | 792 | warning(238); |
805 | } | | 793 | } |
806 | | | 794 | |
807 | if (tp->t_tspec == STRUCT && tp->t_str->sou_incomplete) { | | 795 | if (tp->t_tspec == STRUCT && tp->t_str->sou_incomplete) { |
808 | /* initialization of incomplete type '%s' */ | | 796 | /* initialization of incomplete type '%s' */ |
809 | error(175, type_name(tp)); | | 797 | error(175, type_name(tp)); |
810 | in->in_err = true; | | 798 | in->in_err = true; |
811 | goto done; | | 799 | goto done; |
812 | } | | 800 | } |
813 | | | 801 | |
814 | if (in->in_brace_level != NULL) | | 802 | if (in->in_brace_level != NULL) |
815 | brace_level_apply_designation(in->in_brace_level); | | 803 | brace_level_apply_designation(in->in_brace_level); |
816 | | | 804 | |
817 | in->in_brace_level = brace_level_new(tp, in->in_brace_level); | | 805 | in->in_brace_level = brace_level_new(tp, in->in_brace_level); |
818 | | | 806 | |
819 | done: | | 807 | done: |
820 | initialization_debug(in); | | 808 | initialization_debug(in); |
821 | debug_leave(); | | 809 | debug_leave(); |
822 | } | | 810 | } |
823 | | | 811 | |
824 | /* C99 6.7.8p22 */ | | 812 | /* C99 6.7.8p22 */ |
825 | static void | | 813 | static void |
826 | initialization_set_size_of_unknown_array(struct initialization *in) | | 814 | initialization_set_size_of_unknown_array(struct initialization *in) |
827 | { | | 815 | { |
828 | | | 816 | |
829 | if (in->in_sym->s_type->t_incomplete_array && | | 817 | if (in->in_sym->s_type->t_incomplete_array && |
830 | in->in_brace_level->bl_enclosing == NULL) | | 818 | in->in_brace_level->bl_enclosing == NULL) |
831 | update_type_of_array_of_unknown_size(in->in_sym, | | 819 | update_type_of_array_of_unknown_size(in->in_sym, |
832 | in->in_brace_level->bl_array_next_subscript); | | 820 | in->in_brace_level->bl_array_next_subscript); |
833 | } | | 821 | } |
834 | | | 822 | |
835 | static void | | 823 | static void |
836 | initialization_end_brace_level(struct initialization *in) | | 824 | initialization_end_brace_level(struct initialization *in) |
837 | { | | 825 | { |
838 | struct brace_level *bl; | | 826 | struct brace_level *bl; |
839 | | | 827 | |
840 | if (in->in_err) | | 828 | if (in->in_err) |
841 | return; | | 829 | return; |
842 | | | 830 | |
843 | debug_enter(); | | 831 | debug_enter(); |
844 | | | 832 | |
845 | initialization_set_size_of_unknown_array(in); | | 833 | initialization_set_size_of_unknown_array(in); |
846 | | | 834 | |
847 | bl = in->in_brace_level; | | 835 | bl = in->in_brace_level; |
848 | in->in_brace_level = bl->bl_enclosing; | | 836 | in->in_brace_level = bl->bl_enclosing; |
849 | brace_level_free(bl); | | 837 | brace_level_free(bl); |
| | | 838 | bl = in->in_brace_level; |
850 | | | 839 | |
851 | if (in->in_brace_level != NULL) { | | 840 | if (bl != NULL) |
852 | brace_level_advance(in->in_brace_level); | | 841 | brace_level_advance(bl); |
853 | brace_level_remove_designation(in->in_brace_level); | | 842 | if (bl != NULL) |
854 | } | | 843 | designation_reset(&bl->bl_designation); |
855 | | | 844 | |
856 | initialization_debug(in); | | 845 | initialization_debug(in); |
857 | debug_leave(); | | 846 | debug_leave(); |
858 | } | | 847 | } |
859 | | | 848 | |
860 | static void | | 849 | static void |
861 | initialization_add_designator(struct initialization *in, | | 850 | initialization_add_designator(struct initialization *in, |
862 | const char *name, size_t subscript) | | 851 | const char *name, size_t subscript) |
863 | { | | 852 | { |
864 | | | 853 | |
865 | if (in->in_err) | | 854 | if (in->in_err) |
866 | return; | | 855 | return; |
867 | | | 856 | |
868 | lint_assert(in->in_brace_level != NULL); | | 857 | lint_assert(in->in_brace_level != NULL); |
869 | designation_add(&in->in_brace_level->bl_designation, name, subscript); | | 858 | designation_add(&in->in_brace_level->bl_designation, name, subscript); |
870 | } | | 859 | } |
871 | | | 860 | |
872 | static void | | | |
873 | initialization_remove_designation(struct initialization *in) | | | |
874 | { | | | |
875 | | | | |
876 | if (in->in_brace_level != NULL) | | | |
877 | brace_level_remove_designation(in->in_brace_level); | | | |
878 | } | | | |
879 | | | | |
880 | /* | | 861 | /* |
881 | * An object with automatic storage duration that has a single initializer | | 862 | * An object with automatic storage duration that has a single initializer |
882 | * expression without braces and is not an array is initialized by delegating | | 863 | * expression without braces and is not an array is initialized by delegating |
883 | * to the ASSIGN operator. | | 864 | * to the ASSIGN operator. |
884 | */ | | 865 | */ |
885 | static bool | | 866 | static bool |
886 | initialization_expr_using_assign(struct initialization *in, tnode_t *rn) | | 867 | initialization_expr_using_assign(struct initialization *in, tnode_t *rn) |
887 | { | | 868 | { |
888 | tnode_t *ln, *tn; | | 869 | tnode_t *ln, *tn; |
889 | | | 870 | |
890 | if (!has_automatic_storage_duration(in->in_sym)) | | 871 | if (!has_automatic_storage_duration(in->in_sym)) |
891 | return false; | | 872 | return false; |
892 | if (in->in_brace_level != NULL) | | 873 | if (in->in_brace_level != NULL) |
893 | return false; | | 874 | return false; |
894 | if (in->in_sym->s_type->t_tspec == ARRAY) | | 875 | if (in->in_sym->s_type->t_tspec == ARRAY) |
895 | return false; | | 876 | return false; |
896 | | | 877 | |
897 | debug_step("handing over to ASSIGN"); | | 878 | debug_step("handing over to ASSIGN"); |
898 | | | 879 | |
899 | ln = new_name_node(in->in_sym, 0); | | 880 | ln = new_name_node(in->in_sym, 0); |
900 | ln->tn_type = tduptyp(ln->tn_type); | | 881 | ln->tn_type = tduptyp(ln->tn_type); |
901 | ln->tn_type->t_const = false; | | 882 | ln->tn_type->t_const = false; |
902 | | | 883 | |
903 | tn = build(ASSIGN, ln, rn); | | 884 | tn = build(ASSIGN, ln, rn); |
904 | expr(tn, false, false, false, false); | | 885 | expr(tn, false, false, false, false); |
905 | | | 886 | |
906 | return true; | | 887 | return true; |
907 | } | | 888 | } |
908 | | | 889 | |
909 | /* Initialize a character array or wchar_t array with a string literal. */ | | 890 | /* Initialize a character array or wchar_t array with a string literal. */ |
910 | static bool | | 891 | static bool |
911 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) | | 892 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) |
912 | { | | 893 | { |
913 | struct brace_level *bl; | | 894 | struct brace_level *bl; |
914 | const type_t *tp; | | 895 | const type_t *tp; |
915 | strg_t *strg; | | 896 | strg_t *strg; |
916 | | | 897 | |
917 | if (tn->tn_op != STRING) | | 898 | if (tn->tn_op != STRING) |
918 | return false; | | 899 | return false; |
919 | | | 900 | |
920 | bl = in->in_brace_level; | | 901 | bl = in->in_brace_level; |
921 | tp = initialization_sub_type(in); | | 902 | tp = initialization_sub_type(in); |
922 | strg = tn->tn_string; | | 903 | strg = tn->tn_string; |
923 | | | 904 | |
924 | if (!is_string_array(tp, strg->st_tspec)) | | 905 | if (!is_string_array(tp, strg->st_tspec)) |
925 | return false; | | 906 | return false; |
926 | if (bl != NULL && tp->t_tspec != ARRAY && | | 907 | if (bl != NULL && tp->t_tspec != ARRAY && |
927 | bl->bl_array_next_subscript != 0) | | 908 | bl->bl_array_next_subscript != 0) |
928 | return false; | | 909 | return false; |
929 | | | 910 | |
930 | if (bl != NULL && tp->t_dim < (int)strg->st_len) { | | 911 | if (bl != NULL && tp->t_dim < (int)strg->st_len) { |
931 | /* non-null byte ignored in string initializer */ | | 912 | /* non-null byte ignored in string initializer */ |
932 | warning(187); | | 913 | warning(187); |
933 | } | | 914 | } |
934 | | | 915 | |
935 | if (tp == in->in_sym->s_type && tp->t_incomplete_array) { | | 916 | if (tp == in->in_sym->s_type && tp->t_incomplete_array) { |
936 | if (bl != NULL) { | | 917 | if (bl != NULL) { |
937 | bl->bl_array_next_subscript = strg->st_len + 1; | | 918 | bl->bl_array_next_subscript = strg->st_len + 1; |
938 | /* see initialization_set_size_of_unknown_array */ | | 919 | /* see initialization_set_size_of_unknown_array */ |
939 | } else | | 920 | } else |
940 | update_type_of_array_of_unknown_size(in->in_sym, | | 921 | update_type_of_array_of_unknown_size(in->in_sym, |
941 | strg->st_len + 1); | | 922 | strg->st_len + 1); |
942 | } | | 923 | } |
943 | | | 924 | |
944 | return true; | | 925 | return true; |
945 | } | | 926 | } |
946 | | | 927 | |
947 | /* | | 928 | /* |
948 | * Initialize a single sub-object as part of the currently ongoing | | 929 | * Initialize a single sub-object as part of the currently ongoing |
949 | * initialization. | | 930 | * initialization. |
950 | */ | | 931 | */ |
951 | static void | | 932 | static void |
952 | initialization_expr(struct initialization *in, tnode_t *tn) | | 933 | initialization_expr(struct initialization *in, tnode_t *tn) |
953 | { | | 934 | { |
| | | 935 | struct brace_level *bl; |
954 | const type_t *tp; | | 936 | const type_t *tp; |
955 | | | 937 | |
956 | if (in->in_err) | | 938 | if (in->in_err) |
957 | return; | | 939 | return; |
958 | | | 940 | |
959 | if (in->in_brace_level != NULL && | | 941 | bl = in->in_brace_level; |
960 | in->in_brace_level->bl_omitted_braces) | | 942 | if (bl != NULL && bl->bl_omitted_braces) |
961 | return; | | 943 | return; |
962 | | | 944 | |
963 | debug_enter(); | | 945 | debug_enter(); |
964 | | | 946 | |
965 | if (tn == NULL) | | 947 | if (tn == NULL) |
966 | goto advance; | | 948 | goto advance; |
967 | if (initialization_expr_using_assign(in, tn)) | | 949 | if (initialization_expr_using_assign(in, tn)) |
968 | goto done; | | 950 | goto done; |
969 | if (initialization_init_array_using_string(in, tn)) | | 951 | if (initialization_init_array_using_string(in, tn)) |
970 | goto advance; | | 952 | goto advance; |
971 | | | 953 | |
972 | if (in->in_brace_level != NULL) | | 954 | if (bl != NULL) |
973 | brace_level_apply_designation(in->in_brace_level); | | 955 | brace_level_apply_designation(bl); |
974 | tp = initialization_sub_type(in); | | 956 | tp = initialization_sub_type(in); |
975 | if (tp == NULL) | | 957 | if (tp == NULL) |
976 | goto done; | | 958 | goto done; |
977 | | | 959 | |
978 | if (in->in_brace_level == NULL && !is_scalar(tp->t_tspec)) { | | 960 | if (bl == NULL && !is_scalar(tp->t_tspec)) { |
979 | /* {}-enclosed initializer required */ | | 961 | /* {}-enclosed initializer required */ |
980 | error(181); | | 962 | error(181); |
981 | goto done; | | 963 | goto done; |
982 | } | | 964 | } |
983 | | | 965 | |
984 | /* | | 966 | /* |
985 | * Hack to accept initializations with omitted braces, see | | 967 | * Hack to accept initializations with omitted braces, see |
986 | * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and | | 968 | * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and |
987 | * Clang already warn about this at level -Wall, there is no point | | 969 | * Clang already warn about this at level -Wall, there is no point |
988 | * in letting lint check this again. | | 970 | * in letting lint check this again. |
989 | */ | | 971 | */ |
990 | if (is_scalar(tn->tn_type->t_tspec) && | | 972 | if (is_scalar(tn->tn_type->t_tspec) && |
991 | tp->t_tspec == ARRAY && | | 973 | tp->t_tspec == ARRAY && |
992 | in->in_brace_level != NULL) { | | 974 | bl != NULL) { |
993 | in->in_brace_level->bl_omitted_braces = true; | | 975 | bl->bl_omitted_braces = true; |
994 | goto done; | | 976 | goto done; |
995 | } | | 977 | } |
996 | | | 978 | |
997 | debug_step("expecting '%s', expression has '%s'", | | 979 | debug_step("expecting '%s', expression has '%s'", |
998 | type_name(tp), type_name(tn->tn_type)); | | 980 | type_name(tp), type_name(tn->tn_type)); |
999 | check_init_expr(tp, in->in_sym, tn); | | 981 | check_init_expr(tp, in->in_sym, tn); |
1000 | | | 982 | |
1001 | advance: | | 983 | advance: |
1002 | if (in->in_brace_level != NULL) | | 984 | if (bl != NULL) |
1003 | brace_level_advance(in->in_brace_level); | | 985 | brace_level_advance(bl); |
1004 | done: | | 986 | done: |
1005 | initialization_remove_designation(in); | | 987 | if (bl != NULL) |
| | | 988 | designation_reset(&bl->bl_designation); |
| | | 989 | |
1006 | initialization_debug(in); | | 990 | initialization_debug(in); |
1007 | debug_leave(); | | 991 | debug_leave(); |
1008 | } | | 992 | } |
1009 | | | 993 | |
1010 | | | 994 | |
1011 | static struct initialization *init; | | 995 | static struct initialization *init; |
1012 | | | 996 | |
1013 | | | 997 | |
1014 | static struct initialization * | | 998 | static struct initialization * |
1015 | current_init(void) | | 999 | current_init(void) |
1016 | { | | 1000 | { |
1017 | | | 1001 | |
1018 | lint_assert(init != NULL); | | 1002 | lint_assert(init != NULL); |
1019 | return init; | | 1003 | return init; |
1020 | } | | 1004 | } |
1021 | | | 1005 | |
1022 | sym_t ** | | 1006 | sym_t ** |
1023 | current_initsym(void) | | 1007 | current_initsym(void) |
1024 | { | | 1008 | { |
1025 | | | 1009 | |
1026 | return ¤t_init()->in_sym; | | 1010 | return ¤t_init()->in_sym; |
1027 | } | | 1011 | } |
1028 | | | 1012 | |
1029 | void | | 1013 | void |
1030 | begin_initialization(sym_t *sym) | | 1014 | begin_initialization(sym_t *sym) |
1031 | { | | 1015 | { |
1032 | struct initialization *in; | | 1016 | struct initialization *in; |
1033 | | | 1017 | |
1034 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); | | 1018 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); |
1035 | #ifdef DEBUG | | 1019 | #ifdef DEBUG |
1036 | debug_indentation++; | | 1020 | debug_indentation++; |
1037 | #endif | | 1021 | #endif |
1038 | | | 1022 | |
1039 | in = initialization_new(sym); | | 1023 | in = initialization_new(sym); |
1040 | in->in_enclosing = init; | | 1024 | in->in_enclosing = init; |
1041 | init = in; | | 1025 | init = in; |
1042 | } | | 1026 | } |
1043 | | | 1027 | |
1044 | void | | 1028 | void |
1045 | end_initialization(void) | | 1029 | end_initialization(void) |
1046 | { | | 1030 | { |
1047 | struct initialization *in; | | 1031 | struct initialization *in; |
1048 | | | 1032 | |
1049 | in = init; | | 1033 | in = init; |
1050 | init = in->in_enclosing; | | 1034 | init = in->in_enclosing; |
1051 | initialization_free(in); | | 1035 | initialization_free(in); |
1052 | | | 1036 | |
1053 | #ifdef DEBUG | | 1037 | #ifdef DEBUG |
1054 | debug_indentation--; | | 1038 | debug_indentation--; |
1055 | #endif | | 1039 | #endif |
1056 | debug_step("end initialization"); | | 1040 | debug_step("end initialization"); |
1057 | } | | 1041 | } |
1058 | | | 1042 | |
1059 | void | | 1043 | void |
1060 | add_designator_member(sbuf_t *sb) | | 1044 | add_designator_member(sbuf_t *sb) |
1061 | { | | 1045 | { |
1062 | | | 1046 | |
1063 | initialization_add_designator(current_init(), sb->sb_name, 0); | | 1047 | initialization_add_designator(current_init(), sb->sb_name, 0); |
1064 | } | | 1048 | } |
1065 | | | 1049 | |
1066 | void | | 1050 | void |
1067 | add_designator_subscript(range_t range) | | 1051 | add_designator_subscript(range_t range) |
1068 | { | | 1052 | { |
1069 | | | 1053 | |
1070 | initialization_add_designator(current_init(), NULL, range.hi); | | 1054 | initialization_add_designator(current_init(), NULL, range.hi); |
1071 | } | | 1055 | } |
1072 | | | 1056 | |
1073 | void | | 1057 | void |
1074 | init_lbrace(void) | | 1058 | init_lbrace(void) |
1075 | { | | 1059 | { |
1076 | | | 1060 | |
1077 | initialization_begin_brace_level(current_init()); | | 1061 | initialization_begin_brace_level(current_init()); |
1078 | } | | 1062 | } |
1079 | | | 1063 | |
1080 | void | | 1064 | void |
1081 | init_expr(tnode_t *tn) | | 1065 | init_expr(tnode_t *tn) |
1082 | { | | 1066 | { |
1083 | | | 1067 | |
1084 | initialization_expr(current_init(), tn); | | 1068 | initialization_expr(current_init(), tn); |
1085 | } | | 1069 | } |
1086 | | | 1070 | |
1087 | void | | 1071 | void |
1088 | init_rbrace(void) | | 1072 | init_rbrace(void) |
1089 | { | | 1073 | { |
1090 | | | 1074 | |
1091 | initialization_end_brace_level(current_init()); | | 1075 | initialization_end_brace_level(current_init()); |
1092 | } | | 1076 | } |