]>
Commit | Line | Data |
---|---|---|
8d08fdba MS |
1 | /* Report error messages, build initializers, and perform |
2 | some front-end optimizations for C++ compiler. | |
a945c346 | 3 | Copyright (C) 1987-2024 Free Software Foundation, Inc. |
8d08fdba MS |
4 | Hacked by Michael Tiemann (tiemann@cygnus.com) |
5 | ||
f5adbb8d | 6 | This file is part of GCC. |
8d08fdba | 7 | |
f5adbb8d | 8 | GCC is free software; you can redistribute it and/or modify |
8d08fdba | 9 | it under the terms of the GNU General Public License as published by |
e77f031d | 10 | the Free Software Foundation; either version 3, or (at your option) |
8d08fdba MS |
11 | any later version. |
12 | ||
f5adbb8d | 13 | GCC is distributed in the hope that it will be useful, |
8d08fdba MS |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
e77f031d NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
8d08fdba MS |
21 | |
22 | ||
23 | /* This file is part of the C++ front end. | |
24 | It contains routines to build C++ expressions given their operands, | |
25 | including computing the types of the result, C and C++ specific error | |
5088b058 | 26 | checks, and some optimization. */ |
8d08fdba MS |
27 | |
28 | #include "config.h" | |
8d052bc7 | 29 | #include "system.h" |
4977bab6 | 30 | #include "coretypes.h" |
2adfab87 | 31 | #include "cp-tree.h" |
d8a2d370 DN |
32 | #include "stor-layout.h" |
33 | #include "varasm.h" | |
4cd5a50a | 34 | #include "intl.h" |
8ba109ce | 35 | #include "gcc-rich-location.h" |
02a32ab4 | 36 | #include "target.h" |
8d08fdba | 37 | |
4038c495 | 38 | static tree |
08c35030 | 39 | process_init_constructor (tree type, tree init, int nested, int flags, |
a8c55cac | 40 | tsubst_flags_t complain); |
4038c495 | 41 | |
8d08fdba | 42 | |
8d08fdba MS |
43 | /* Print an error message stemming from an attempt to use |
44 | BASETYPE as a base class for TYPE. */ | |
e92cc029 | 45 | |
8d08fdba | 46 | tree |
0a8cb79e | 47 | error_not_base_type (tree basetype, tree type) |
8d08fdba MS |
48 | { |
49 | if (TREE_CODE (basetype) == FUNCTION_DECL) | |
4f1c5b7d | 50 | basetype = DECL_CONTEXT (basetype); |
a82e1a7d | 51 | error ("type %qT is not a base type for type %qT", basetype, type); |
8d08fdba MS |
52 | return error_mark_node; |
53 | } | |
54 | ||
55 | tree | |
0a8cb79e | 56 | binfo_or_else (tree base, tree type) |
8d08fdba | 57 | { |
22854930 PC |
58 | tree binfo = lookup_base (type, base, ba_unique, |
59 | NULL, tf_warning_or_error); | |
2db1ab2d NS |
60 | |
61 | if (binfo == error_mark_node) | |
62 | return NULL_TREE; | |
63 | else if (!binfo) | |
64 | error_not_base_type (base, type); | |
65 | return binfo; | |
8d08fdba MS |
66 | } |
67 | ||
8d08fdba | 68 | /* According to ARM $7.1.6, "A `const' object may be initialized, but its |
fabb00fc | 69 | value may not be changed thereafter. */ |
e92cc029 | 70 | |
8d08fdba | 71 | void |
d4714a1b | 72 | cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring) |
8d08fdba | 73 | { |
4cd5a50a PB |
74 | |
75 | /* This macro is used to emit diagnostics to ensure that all format | |
76 | strings are complete sentences, visible to gettext and checked at | |
77 | compile time. */ | |
78 | ||
d4714a1b | 79 | #define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG) \ |
4cd5a50a PB |
80 | do { \ |
81 | switch (errstring) \ | |
82 | { \ | |
4816c593 | 83 | case lv_assign: \ |
d4714a1b | 84 | error_at (LOC, AS, ARG); \ |
4cd5a50a | 85 | break; \ |
4816c593 | 86 | case lv_asm: \ |
d4714a1b | 87 | error_at (LOC, ASM, ARG); \ |
4cd5a50a | 88 | break; \ |
4816c593 | 89 | case lv_increment: \ |
d4714a1b | 90 | error_at (LOC, IN, ARG); \ |
4cd5a50a | 91 | break; \ |
d4714a1b JJ |
92 | case lv_decrement: \ |
93 | error_at (LOC, DE, ARG); \ | |
4cd5a50a PB |
94 | break; \ |
95 | default: \ | |
96 | gcc_unreachable (); \ | |
97 | } \ | |
98 | } while (0) | |
8d08fdba | 99 | |
4816c593 NF |
100 | /* Handle C++-specific things first. */ |
101 | ||
5a6ccc94 | 102 | if (VAR_P (arg) |
4816c593 NF |
103 | && DECL_LANG_SPECIFIC (arg) |
104 | && DECL_IN_AGGR_P (arg) | |
105 | && !TREE_STATIC (arg)) | |
d4714a1b JJ |
106 | ERROR_FOR_ASSIGNMENT (loc, |
107 | G_("assignment of constant field %qD"), | |
108 | G_("constant field %qD used as %<asm%> output"), | |
109 | G_("increment of constant field %qD"), | |
110 | G_("decrement of constant field %qD"), | |
4816c593 | 111 | arg); |
591cb3cf | 112 | else if (INDIRECT_REF_P (arg) |
9f613f06 | 113 | && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0))) |
5a6ccc94 | 114 | && (VAR_P (TREE_OPERAND (arg, 0)) |
0cbd7506 | 115 | || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL)) |
d4714a1b JJ |
116 | ERROR_FOR_ASSIGNMENT (loc, |
117 | G_("assignment of read-only reference %qD"), | |
118 | G_("read-only reference %qD used as %<asm%> output"), | |
119 | G_("increment of read-only reference %qD"), | |
120 | G_("decrement of read-only reference %qD"), | |
121 | TREE_OPERAND (arg, 0)); | |
69851283 | 122 | else |
d4714a1b | 123 | readonly_error (loc, arg, errstring); |
8d08fdba | 124 | } |
7fb213d8 | 125 | \f |
a7a64a77 MM |
126 | /* If TYPE has abstract virtual functions, issue an error about trying |
127 | to create an object of that type. DECL is the object declared, or | |
2df663cc JM |
128 | NULL_TREE if the declaration is unavailable, in which case USE specifies |
129 | the kind of invalid use. Returns 1 if an error occurred; zero if | |
130 | all was well. */ | |
e92cc029 | 131 | |
2df663cc | 132 | static int |
c17fa0f2 PP |
133 | abstract_virtuals_error (tree decl, tree type, abstract_class_use use, |
134 | tsubst_flags_t complain) | |
8d08fdba | 135 | { |
9771b263 | 136 | vec<tree, va_gc> *pure; |
c8094d83 | 137 | |
baf38d2e JM |
138 | if (TREE_CODE (type) == ARRAY_TYPE) |
139 | { | |
140 | decl = NULL_TREE; | |
141 | use = ACU_ARRAY; | |
142 | type = strip_array_types (type); | |
143 | } | |
144 | ||
7fb213d8 GB |
145 | /* This function applies only to classes. Any other entity can never |
146 | be abstract. */ | |
147 | if (!CLASS_TYPE_P (type)) | |
148 | return 0; | |
98fba7f7 | 149 | type = TYPE_MAIN_VARIANT (type); |
7fb213d8 | 150 | |
a0c06853 JM |
151 | #if 0 |
152 | /* Instantiation here seems to be required by the standard, | |
153 | but breaks e.g. boost::bind. FIXME! */ | |
2b24855e JM |
154 | /* In SFINAE, non-N3276 context, force instantiation. */ |
155 | if (!(complain & (tf_error|tf_decltype))) | |
9f5d44f4 | 156 | complete_type (type); |
a0c06853 | 157 | #endif |
9f5d44f4 | 158 | |
e60505a5 NS |
159 | if (!TYPE_SIZE (type)) |
160 | /* TYPE is being defined, and during that time | |
161 | CLASSTYPE_PURE_VIRTUALS holds the inline friends. */ | |
162 | return 0; | |
163 | ||
585b44d3 NS |
164 | pure = CLASSTYPE_PURE_VIRTUALS (type); |
165 | if (!pure) | |
166 | return 0; | |
167 | ||
2b8497cd JM |
168 | if (!(complain & tf_error)) |
169 | return 1; | |
170 | ||
097f82ec | 171 | auto_diagnostic_group d; |
8d08fdba MS |
172 | if (decl) |
173 | { | |
5a6ccc94 | 174 | if (VAR_P (decl)) |
dee15844 JM |
175 | error ("cannot declare variable %q+D to be of abstract " |
176 | "type %qT", decl, type); | |
8d08fdba | 177 | else if (TREE_CODE (decl) == PARM_DECL) |
2df663cc JM |
178 | { |
179 | if (DECL_NAME (decl)) | |
180 | error ("cannot declare parameter %q+D to be of abstract type %qT", | |
181 | decl, type); | |
182 | else | |
183 | error ("cannot declare parameter to be of abstract type %qT", | |
184 | type); | |
185 | } | |
8d08fdba | 186 | else if (TREE_CODE (decl) == FIELD_DECL) |
dee15844 JM |
187 | error ("cannot declare field %q+D to be of abstract type %qT", |
188 | decl, type); | |
8d08fdba MS |
189 | else if (TREE_CODE (decl) == FUNCTION_DECL |
190 | && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) | |
dee15844 | 191 | error ("invalid abstract return type for member function %q+#D", decl); |
8d08fdba | 192 | else if (TREE_CODE (decl) == FUNCTION_DECL) |
dee15844 | 193 | error ("invalid abstract return type for function %q+#D", decl); |
9dc6f476 | 194 | else if (identifier_p (decl)) |
dee15844 | 195 | /* Here we do not have location information. */ |
a82e1a7d | 196 | error ("invalid abstract type %qT for %qE", type, decl); |
da291c87 | 197 | else |
dee15844 | 198 | error ("invalid abstract type for %q+D", decl); |
8d08fdba | 199 | } |
2df663cc JM |
200 | else switch (use) |
201 | { | |
202 | case ACU_ARRAY: | |
203 | error ("creating array of %qT, which is an abstract class type", type); | |
204 | break; | |
205 | case ACU_CAST: | |
206 | error ("invalid cast to abstract class type %qT", type); | |
207 | break; | |
208 | case ACU_NEW: | |
209 | error ("invalid new-expression of abstract class type %qT", type); | |
210 | break; | |
211 | case ACU_RETURN: | |
212 | error ("invalid abstract return type %qT", type); | |
213 | break; | |
214 | case ACU_PARM: | |
215 | error ("invalid abstract parameter type %qT", type); | |
216 | break; | |
217 | case ACU_THROW: | |
218 | error ("expression of abstract class type %qT cannot " | |
219 | "be used in throw-expression", type); | |
220 | break; | |
221 | case ACU_CATCH: | |
a9c697b8 | 222 | error ("cannot declare %<catch%> parameter to be of abstract " |
2df663cc JM |
223 | "class type %qT", type); |
224 | break; | |
225 | default: | |
226 | error ("cannot allocate an object of abstract type %qT", type); | |
227 | } | |
4a67c9e9 | 228 | |
8d08fdba | 229 | /* Only go through this once. */ |
9771b263 | 230 | if (pure->length ()) |
8d08fdba | 231 | { |
585b44d3 NS |
232 | unsigned ix; |
233 | tree fn; | |
c8094d83 | 234 | |
c5d75364 MLI |
235 | inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), |
236 | " because the following virtual functions are pure within %qT:", | |
237 | type); | |
da291c87 | 238 | |
9771b263 | 239 | FOR_EACH_VEC_ELT (*pure, ix, fn) |
367f06ae PC |
240 | if (! DECL_CLONED_FUNCTION_P (fn) |
241 | || DECL_COMPLETE_DESTRUCTOR_P (fn)) | |
a9c697b8 | 242 | inform (DECL_SOURCE_LOCATION (fn), " %#qD", fn); |
367f06ae | 243 | |
585b44d3 | 244 | /* Now truncate the vector. This leaves it non-null, so we know |
0cbd7506 MS |
245 | there are pure virtuals, but empty so we don't list them out |
246 | again. */ | |
9771b263 | 247 | pure->truncate (0); |
8d08fdba | 248 | } |
a7a64a77 MM |
249 | |
250 | return 1; | |
8d08fdba MS |
251 | } |
252 | ||
2df663cc | 253 | int |
c17fa0f2 PP |
254 | abstract_virtuals_error (tree decl, tree type, |
255 | tsubst_flags_t complain /* = tf_warning_or_error */) | |
2df663cc | 256 | { |
c17fa0f2 | 257 | return abstract_virtuals_error (decl, type, ACU_UNKNOWN, complain); |
2df663cc JM |
258 | } |
259 | ||
2b8497cd | 260 | int |
c17fa0f2 PP |
261 | abstract_virtuals_error (abstract_class_use use, tree type, |
262 | tsubst_flags_t complain /* = tf_warning_or_error */) | |
2b8497cd | 263 | { |
c17fa0f2 | 264 | return abstract_virtuals_error (NULL_TREE, type, use, complain); |
2b8497cd JM |
265 | } |
266 | ||
2df663cc | 267 | |
bdb5a9a3 PC |
268 | /* Print an inform about the declaration of the incomplete type TYPE. */ |
269 | ||
270 | void | |
271 | cxx_incomplete_type_inform (const_tree type) | |
272 | { | |
0c018b6f PC |
273 | if (!TYPE_MAIN_DECL (type)) |
274 | return; | |
275 | ||
bdb5a9a3 PC |
276 | location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)); |
277 | tree ptype = strip_top_quals (CONST_CAST_TREE (type)); | |
278 | ||
279 | if (current_class_type | |
280 | && TYPE_BEING_DEFINED (current_class_type) | |
281 | && same_type_p (ptype, current_class_type)) | |
282 | inform (loc, "definition of %q#T is not complete until " | |
283 | "the closing brace", ptype); | |
284 | else if (!TYPE_TEMPLATE_INFO (ptype)) | |
285 | inform (loc, "forward declaration of %q#T", ptype); | |
286 | else | |
287 | inform (loc, "declaration of %q#T", ptype); | |
288 | } | |
289 | ||
8d08fdba MS |
290 | /* Print an error message for invalid use of an incomplete type. |
291 | VALUE is the expression that was used (or 0 if that isn't known) | |
71205d17 MLI |
292 | and TYPE is the type that was invalid. DIAG_KIND indicates the |
293 | type of diagnostic (see diagnostic.def). */ | |
8d08fdba | 294 | |
fdb8c06b | 295 | bool |
4f2e1536 MP |
296 | cxx_incomplete_type_diagnostic (location_t loc, const_tree value, |
297 | const_tree type, diagnostic_t diag_kind) | |
8d08fdba | 298 | { |
7fb80849 | 299 | bool is_decl = false, complained = false; |
23b4deba | 300 | |
8d08fdba MS |
301 | /* Avoid duplicate error message. */ |
302 | if (TREE_CODE (type) == ERROR_MARK) | |
fdb8c06b | 303 | return false; |
8d08fdba | 304 | |
dfd7fdca | 305 | if (value) |
146c8d60 | 306 | { |
dfd7fdca DM |
307 | STRIP_ANY_LOCATION_WRAPPER (value); |
308 | ||
309 | if (VAR_P (value) | |
310 | || TREE_CODE (value) == PARM_DECL | |
311 | || TREE_CODE (value) == FIELD_DECL) | |
312 | { | |
313 | complained = emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (value), 0, | |
314 | "%qD has incomplete type", value); | |
315 | is_decl = true; | |
316 | } | |
317 | } | |
315fb5db | 318 | retry: |
66543169 NS |
319 | /* We must print an error message. Be clever about what it says. */ |
320 | ||
321 | switch (TREE_CODE (type)) | |
8d08fdba | 322 | { |
66543169 NS |
323 | case RECORD_TYPE: |
324 | case UNION_TYPE: | |
325 | case ENUMERAL_TYPE: | |
7fb80849 | 326 | if (!is_decl) |
f3255019 | 327 | complained = emit_diagnostic (diag_kind, loc, 0, |
7fb80849 PC |
328 | "invalid use of incomplete type %q#T", |
329 | type); | |
330 | if (complained) | |
bdb5a9a3 | 331 | cxx_incomplete_type_inform (type); |
66543169 NS |
332 | break; |
333 | ||
334 | case VOID_TYPE: | |
fdb8c06b | 335 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 | 336 | "invalid use of %qT", type); |
66543169 NS |
337 | break; |
338 | ||
339 | case ARRAY_TYPE: | |
340 | if (TYPE_DOMAIN (type)) | |
0cbd7506 MS |
341 | { |
342 | type = TREE_TYPE (type); | |
343 | goto retry; | |
344 | } | |
fdb8c06b | 345 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 | 346 | "invalid use of array with unspecified bounds"); |
66543169 NS |
347 | break; |
348 | ||
349 | case OFFSET_TYPE: | |
350 | bad_member: | |
ff180d72 | 351 | { |
c20c3b42 NS |
352 | tree member = TREE_OPERAND (value, 1); |
353 | if (is_overloaded_fn (member)) | |
354 | member = get_first_fn (member); | |
1f0ed17c | 355 | |
ff180d72 JJ |
356 | if (DECL_FUNCTION_MEMBER_P (member) |
357 | && ! flag_ms_extensions) | |
8ba109ce DM |
358 | { |
359 | gcc_rich_location richloc (loc); | |
360 | /* If "member" has no arguments (other than "this"), then | |
361 | add a fix-it hint. */ | |
362 | if (type_num_arguments (TREE_TYPE (member)) == 1) | |
363 | richloc.add_fixit_insert_after ("()"); | |
fdb8c06b | 364 | complained = emit_diagnostic (diag_kind, &richloc, 0, |
8ba109ce DM |
365 | "invalid use of member function %qD " |
366 | "(did you forget the %<()%> ?)", member); | |
367 | } | |
ff180d72 | 368 | else |
fdb8c06b | 369 | complained = emit_diagnostic (diag_kind, loc, 0, |
7e4756e8 PC |
370 | "invalid use of member %qD " |
371 | "(did you forget the %<&%> ?)", member); | |
ff180d72 | 372 | } |
66543169 NS |
373 | break; |
374 | ||
375 | case TEMPLATE_TYPE_PARM: | |
86a09a9e | 376 | if (is_auto (type)) |
9a642cca JM |
377 | { |
378 | if (CLASS_PLACEHOLDER_TEMPLATE (type)) | |
fdb8c06b | 379 | complained = emit_diagnostic (diag_kind, loc, 0, |
9a642cca JM |
380 | "invalid use of placeholder %qT", type); |
381 | else | |
fdb8c06b | 382 | complained = emit_diagnostic (diag_kind, loc, 0, |
9a642cca JM |
383 | "invalid use of %qT", type); |
384 | } | |
86a09a9e | 385 | else |
fdb8c06b | 386 | complained = emit_diagnostic (diag_kind, loc, 0, |
86a09a9e | 387 | "invalid use of template type parameter %qT", type); |
7acf7efa VR |
388 | break; |
389 | ||
390 | case BOUND_TEMPLATE_TEMPLATE_PARM: | |
fdb8c06b | 391 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 MLI |
392 | "invalid use of template template parameter %qT", |
393 | TYPE_NAME (type)); | |
66543169 NS |
394 | break; |
395 | ||
11a751ff | 396 | case TYPE_PACK_EXPANSION: |
fdb8c06b | 397 | complained = emit_diagnostic (diag_kind, loc, 0, |
11a751ff NK |
398 | "invalid use of pack expansion %qT", type); |
399 | break; | |
400 | ||
8fcd79cb | 401 | case TYPENAME_TYPE: |
2a54351b | 402 | case DECLTYPE_TYPE: |
fdb8c06b | 403 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 | 404 | "invalid use of dependent type %qT", type); |
8fcd79cb MM |
405 | break; |
406 | ||
fbfc8363 | 407 | case LANG_TYPE: |
09841630 JM |
408 | if (type == init_list_type_node) |
409 | { | |
fdb8c06b | 410 | complained = emit_diagnostic (diag_kind, loc, 0, |
09841630 JM |
411 | "invalid use of brace-enclosed initializer list"); |
412 | break; | |
413 | } | |
fbfc8363 | 414 | gcc_assert (type == unknown_type_node); |
66543169 | 415 | if (value && TREE_CODE (value) == COMPONENT_REF) |
0cbd7506 | 416 | goto bad_member; |
66543169 | 417 | else if (value && TREE_CODE (value) == ADDR_EXPR) |
fdb8c06b | 418 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 MLI |
419 | "address of overloaded function with no contextual " |
420 | "type information"); | |
66543169 | 421 | else if (value && TREE_CODE (value) == OVERLOAD) |
fdb8c06b | 422 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 | 423 | "overloaded function with no contextual type information"); |
66543169 | 424 | else |
fdb8c06b | 425 | complained = emit_diagnostic (diag_kind, loc, 0, |
71205d17 | 426 | "insufficient contextual information to determine type"); |
66543169 | 427 | break; |
c8094d83 | 428 | |
66543169 | 429 | default: |
315fb5db | 430 | gcc_unreachable (); |
8d08fdba | 431 | } |
fdb8c06b JM |
432 | |
433 | return complained; | |
8d08fdba MS |
434 | } |
435 | ||
4f2e1536 MP |
436 | /* Print an error message for invalid use of an incomplete type. |
437 | VALUE is the expression that was used (or 0 if that isn't known) | |
438 | and TYPE is the type that was invalid. */ | |
439 | ||
23b4deba | 440 | void |
4f2e1536 | 441 | cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type) |
23b4deba | 442 | { |
4f2e1536 | 443 | cxx_incomplete_type_diagnostic (loc, value, type, DK_ERROR); |
23b4deba AO |
444 | } |
445 | ||
8d08fdba | 446 | \f |
ce0ab8fb JM |
447 | /* We've just initialized subobject SUB; also insert a TARGET_EXPR with an |
448 | EH-only cleanup for SUB. Because of EH region nesting issues, we need to | |
449 | make the cleanup conditional on a flag that we will clear once the object is | |
450 | fully initialized, so push a new flag onto FLAGS. */ | |
451 | ||
452 | static void | |
453 | maybe_push_temp_cleanup (tree sub, vec<tree,va_gc> **flags) | |
454 | { | |
53cac72c JM |
455 | if (!flag_exceptions) |
456 | return; | |
ce0ab8fb JM |
457 | if (tree cleanup |
458 | = cxx_maybe_build_cleanup (sub, tf_warning_or_error)) | |
459 | { | |
460 | tree tx = get_target_expr (boolean_true_node); | |
461 | tree flag = TARGET_EXPR_SLOT (tx); | |
462 | CLEANUP_EH_ONLY (tx) = true; | |
463 | TARGET_EXPR_CLEANUP (tx) = build3 (COND_EXPR, void_type_node, | |
464 | flag, cleanup, void_node); | |
465 | add_stmt (tx); | |
466 | vec_safe_push (*flags, flag); | |
467 | } | |
468 | } | |
469 | ||
25ebb82a | 470 | /* The recursive part of split_nonconstant_init. DEST is an lvalue |
953d0c90 RS |
471 | expression to which INIT should be assigned. INIT is a CONSTRUCTOR. |
472 | Return true if the whole of the value was initialized by the | |
473 | generated statements. */ | |
25ebb82a | 474 | |
953d0c90 | 475 | static bool |
40140b73 JM |
476 | split_nonconstant_init_1 (tree dest, tree init, bool last, |
477 | vec<tree,va_gc> **flags) | |
25ebb82a | 478 | { |
a8b98e2f | 479 | unsigned HOST_WIDE_INT idx, tidx = HOST_WIDE_INT_M1U; |
4038c495 GB |
480 | tree field_index, value; |
481 | tree type = TREE_TYPE (dest); | |
482 | tree inner_type = NULL; | |
25ebb82a | 483 | bool array_type_p = false; |
953d0c90 RS |
484 | bool complete_p = true; |
485 | HOST_WIDE_INT num_split_elts = 0; | |
53cac72c | 486 | tree last_split_elt = NULL_TREE; |
25ebb82a | 487 | |
25ebb82a RH |
488 | switch (TREE_CODE (type)) |
489 | { | |
490 | case ARRAY_TYPE: | |
491 | inner_type = TREE_TYPE (type); | |
492 | array_type_p = true; | |
89631a43 JM |
493 | if ((TREE_SIDE_EFFECTS (init) |
494 | && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) | |
1d473b8b | 495 | || vla_type_p (type)) |
89631a43 | 496 | { |
29e4163a JM |
497 | if (!TYPE_DOMAIN (type) |
498 | && TREE_CODE (init) == CONSTRUCTOR | |
499 | && CONSTRUCTOR_NELTS (init)) | |
500 | { | |
501 | /* Flexible array. */ | |
502 | cp_complete_array_type (&type, init, /*default*/true); | |
503 | dest = build1 (VIEW_CONVERT_EXPR, type, dest); | |
504 | } | |
505 | ||
89631a43 | 506 | /* For an array, we only need/want a single cleanup region rather |
beaee0a8 | 507 | than one per element. build_vec_init will handle it. */ |
89631a43 | 508 | tree code = build_vec_init (dest, NULL_TREE, init, false, 1, |
beaee0a8 | 509 | tf_warning_or_error, flags); |
89631a43 JM |
510 | add_stmt (code); |
511 | return true; | |
512 | } | |
25ebb82a RH |
513 | /* FALLTHRU */ |
514 | ||
515 | case RECORD_TYPE: | |
516 | case UNION_TYPE: | |
517 | case QUAL_UNION_TYPE: | |
4038c495 GB |
518 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, |
519 | field_index, value) | |
25ebb82a | 520 | { |
4038c495 GB |
521 | /* The current implementation of this algorithm assumes that |
522 | the field was set for all the elements. This is usually done | |
523 | by process_init_constructor. */ | |
524 | gcc_assert (field_index); | |
25ebb82a RH |
525 | |
526 | if (!array_type_p) | |
527 | inner_type = TREE_TYPE (field_index); | |
528 | ||
beaee0a8 JM |
529 | tree sub; |
530 | if (array_type_p) | |
531 | sub = build4 (ARRAY_REF, inner_type, dest, field_index, | |
532 | NULL_TREE, NULL_TREE); | |
533 | else | |
534 | sub = build3 (COMPONENT_REF, inner_type, dest, field_index, | |
535 | NULL_TREE); | |
536 | ||
40140b73 JM |
537 | bool elt_last = last && idx == CONSTRUCTOR_NELTS (init) - 1; |
538 | ||
119cea98 JM |
539 | /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can |
540 | handle cleanup flags properly. */ | |
541 | gcc_checking_assert (!target_expr_needs_replace (value)); | |
542 | ||
25ebb82a RH |
543 | if (TREE_CODE (value) == CONSTRUCTOR) |
544 | { | |
40140b73 | 545 | if (!split_nonconstant_init_1 (sub, value, elt_last, flags) |
e5d1af8a JJ |
546 | /* For flexible array member with initializer we |
547 | can't remove the initializer, because only the | |
548 | initializer determines how many elements the | |
549 | flexible array member has. */ | |
550 | || (!array_type_p | |
551 | && TREE_CODE (inner_type) == ARRAY_TYPE | |
552 | && TYPE_DOMAIN (inner_type) == NULL | |
553 | && TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE | |
554 | && COMPLETE_TYPE_P (TREE_TYPE (value)) | |
555 | && !integer_zerop (TYPE_SIZE (TREE_TYPE (value))) | |
40140b73 | 556 | && elt_last |
e5d1af8a JJ |
557 | && TYPE_HAS_TRIVIAL_DESTRUCTOR |
558 | (strip_array_types (inner_type)))) | |
953d0c90 | 559 | complete_p = false; |
fa4e8db2 | 560 | else |
a8b98e2f RB |
561 | { |
562 | /* Mark element for removal. */ | |
53cac72c | 563 | last_split_elt = field_index; |
a8b98e2f RB |
564 | CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; |
565 | if (idx < tidx) | |
566 | tidx = idx; | |
567 | num_split_elts++; | |
568 | } | |
25ebb82a | 569 | } |
119cea98 | 570 | else if (tree vi = get_vec_init_expr (value)) |
beaee0a8 | 571 | { |
119cea98 | 572 | add_stmt (expand_vec_init_expr (sub, vi, tf_warning_or_error, |
beaee0a8 JM |
573 | flags)); |
574 | ||
575 | /* Mark element for removal. */ | |
53cac72c | 576 | last_split_elt = field_index; |
beaee0a8 JM |
577 | CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; |
578 | if (idx < tidx) | |
579 | tidx = idx; | |
580 | num_split_elts++; | |
581 | } | |
25ebb82a RH |
582 | else if (!initializer_constant_valid_p (value, inner_type)) |
583 | { | |
4038c495 | 584 | tree code; |
4038c495 | 585 | |
53cac72c JM |
586 | /* Push cleanups for any preceding members with constant |
587 | initialization. */ | |
588 | if (CLASS_TYPE_P (type)) | |
589 | for (tree prev = (last_split_elt ? | |
590 | DECL_CHAIN (last_split_elt) | |
591 | : TYPE_FIELDS (type)); | |
592 | ; prev = DECL_CHAIN (prev)) | |
593 | { | |
0c7bce0a | 594 | prev = next_aggregate_field (prev); |
53cac72c JM |
595 | if (prev == field_index) |
596 | break; | |
597 | tree ptype = TREE_TYPE (prev); | |
8b449dcd | 598 | if (TYPE_P (ptype) && type_build_dtor_call (ptype)) |
53cac72c JM |
599 | { |
600 | tree pcref = build3 (COMPONENT_REF, ptype, dest, prev, | |
601 | NULL_TREE); | |
602 | maybe_push_temp_cleanup (pcref, flags); | |
603 | } | |
604 | } | |
605 | ||
da10c178 RB |
606 | /* Mark element for removal. */ |
607 | CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; | |
a8b98e2f RB |
608 | if (idx < tidx) |
609 | tidx = idx; | |
25ebb82a | 610 | |
41852027 JM |
611 | if (TREE_CODE (field_index) == RANGE_EXPR) |
612 | { | |
613 | /* Use build_vec_init to initialize a range. */ | |
614 | tree low = TREE_OPERAND (field_index, 0); | |
615 | tree hi = TREE_OPERAND (field_index, 1); | |
616 | sub = build4 (ARRAY_REF, inner_type, dest, low, | |
617 | NULL_TREE, NULL_TREE); | |
618 | sub = cp_build_addr_expr (sub, tf_warning_or_error); | |
619 | tree max = size_binop (MINUS_EXPR, hi, low); | |
620 | code = build_vec_init (sub, max, value, false, 0, | |
621 | tf_warning_or_error); | |
622 | add_stmt (code); | |
2cbf3dd7 JJ |
623 | if (tree_fits_shwi_p (max)) |
624 | num_split_elts += tree_to_shwi (max); | |
41852027 | 625 | } |
25ebb82a | 626 | else |
76187e87 | 627 | { |
d75199f7 JM |
628 | /* We may need to add a copy constructor call if |
629 | the field has [[no_unique_address]]. */ | |
32005478 JM |
630 | if (unsafe_return_slot_p (sub)) |
631 | { | |
d75199f7 JM |
632 | /* But not if the initializer is an implicit ctor call |
633 | we just built in digest_init. */ | |
634 | if (TREE_CODE (value) == TARGET_EXPR | |
635 | && TARGET_EXPR_LIST_INIT_P (value) | |
636 | && make_safe_copy_elision (sub, value)) | |
637 | goto build_init; | |
638 | ||
639 | tree name = (DECL_FIELD_IS_BASE (field_index) | |
640 | ? base_ctor_identifier | |
641 | : complete_ctor_identifier); | |
32005478 JM |
642 | releasing_vec args = make_tree_vector_single (value); |
643 | code = build_special_member_call | |
d75199f7 | 644 | (sub, name, &args, inner_type, |
32005478 JM |
645 | LOOKUP_NORMAL, tf_warning_or_error); |
646 | } | |
647 | else | |
d75199f7 JM |
648 | { |
649 | build_init: | |
6ffbf87c | 650 | code = cp_build_init_expr (sub, value); |
d75199f7 | 651 | } |
41852027 | 652 | code = build_stmt (input_location, EXPR_STMT, code); |
41852027 | 653 | add_stmt (code); |
40140b73 JM |
654 | if (!elt_last) |
655 | maybe_push_temp_cleanup (sub, flags); | |
76187e87 | 656 | } |
6addabbb | 657 | |
53cac72c | 658 | last_split_elt = field_index; |
953d0c90 | 659 | num_split_elts++; |
25ebb82a | 660 | } |
25ebb82a | 661 | } |
a8b98e2f RB |
662 | if (num_split_elts == 1) |
663 | CONSTRUCTOR_ELTS (init)->ordered_remove (tidx); | |
664 | else if (num_split_elts > 1) | |
da10c178 RB |
665 | { |
666 | /* Perform the delayed ordered removal of non-constant elements | |
667 | we split out. */ | |
a8b98e2f | 668 | for (idx = tidx; idx < CONSTRUCTOR_NELTS (init); ++idx) |
da10c178 RB |
669 | if (CONSTRUCTOR_ELT (init, idx)->index == NULL_TREE) |
670 | ; | |
671 | else | |
672 | { | |
a8b98e2f | 673 | *CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx); |
da10c178 RB |
674 | ++tidx; |
675 | } | |
676 | vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx); | |
677 | } | |
25ebb82a RH |
678 | break; |
679 | ||
680 | case VECTOR_TYPE: | |
681 | if (!initializer_constant_valid_p (init, type)) | |
682 | { | |
4038c495 | 683 | tree code; |
74aad7cc | 684 | tree cons = copy_node (init); |
25ebb82a | 685 | CONSTRUCTOR_ELTS (init) = NULL; |
74aad7cc | 686 | code = build2 (MODIFY_EXPR, type, dest, cons); |
c2255bc4 | 687 | code = build_stmt (input_location, EXPR_STMT, code); |
325c3691 | 688 | add_stmt (code); |
953d0c90 | 689 | num_split_elts += CONSTRUCTOR_NELTS (init); |
25ebb82a RH |
690 | } |
691 | break; | |
692 | ||
693 | default: | |
315fb5db | 694 | gcc_unreachable (); |
25ebb82a | 695 | } |
b7af94d8 CL |
696 | |
697 | /* The rest of the initializer is now a constant. */ | |
698 | TREE_CONSTANT (init) = 1; | |
942d334e | 699 | TREE_SIDE_EFFECTS (init) = 0; |
f25d7e06 MP |
700 | |
701 | /* We didn't split out anything. */ | |
702 | if (num_split_elts == 0) | |
703 | return false; | |
704 | ||
953d0c90 RS |
705 | return complete_p && complete_ctor_at_level_p (TREE_TYPE (init), |
706 | num_split_elts, inner_type); | |
25ebb82a RH |
707 | } |
708 | ||
c8094d83 | 709 | /* A subroutine of store_init_value. Splits non-constant static |
25ebb82a RH |
710 | initializer INIT into a constant part and generates code to |
711 | perform the non-constant part of the initialization to DEST. | |
712 | Returns the code for the runtime init. */ | |
713 | ||
89631a43 | 714 | tree |
25ebb82a RH |
715 | split_nonconstant_init (tree dest, tree init) |
716 | { | |
717 | tree code; | |
718 | ||
89631a43 JM |
719 | if (TREE_CODE (init) == TARGET_EXPR) |
720 | init = TARGET_EXPR_INITIAL (init); | |
25ebb82a RH |
721 | if (TREE_CODE (init) == CONSTRUCTOR) |
722 | { | |
ce0ab8fb JM |
723 | /* Subobject initializers are not full-expressions. */ |
724 | auto fe = (make_temp_override | |
725 | (current_stmt_tree ()->stmts_are_full_exprs_p, 0)); | |
726 | ||
50867d20 | 727 | init = cp_fully_fold_init (init); |
325c3691 | 728 | code = push_stmt_list (); |
ce0ab8fb | 729 | |
beaee0a8 JM |
730 | /* If the complete object is an array, build_vec_init's cleanup is |
731 | enough. Otherwise, collect flags for disabling subobject | |
732 | cleanups once the complete object is fully constructed. */ | |
733 | vec<tree, va_gc> *flags = nullptr; | |
734 | if (TREE_CODE (TREE_TYPE (dest)) != ARRAY_TYPE) | |
735 | flags = make_tree_vector (); | |
ce0ab8fb | 736 | |
40140b73 | 737 | if (split_nonconstant_init_1 (dest, init, true, &flags)) |
953d0c90 | 738 | init = NULL_TREE; |
ce0ab8fb JM |
739 | |
740 | for (tree f : flags) | |
741 | { | |
742 | /* See maybe_push_temp_cleanup. */ | |
743 | tree d = f; | |
744 | tree i = boolean_false_node; | |
beaee0a8 JM |
745 | if (TREE_CODE (f) == TREE_LIST) |
746 | { | |
747 | /* To disable a build_vec_init cleanup, set | |
748 | iterator = maxindex. */ | |
749 | d = TREE_PURPOSE (f); | |
750 | i = TREE_VALUE (f); | |
751 | ggc_free (f); | |
752 | } | |
ce0ab8fb JM |
753 | add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (d), d, i)); |
754 | } | |
755 | release_tree_vector (flags); | |
756 | ||
325c3691 | 757 | code = pop_stmt_list (code); |
942d334e JM |
758 | if (VAR_P (dest) && !is_local_temp (dest)) |
759 | { | |
760 | DECL_INITIAL (dest) = init; | |
761 | TREE_READONLY (dest) = 0; | |
762 | } | |
763 | else if (init) | |
764 | { | |
6ffbf87c | 765 | tree ie = cp_build_init_expr (dest, init); |
942d334e JM |
766 | code = add_stmt_to_compound (ie, code); |
767 | } | |
25ebb82a | 768 | } |
5a68fae7 JM |
769 | else if (TREE_CODE (init) == STRING_CST |
770 | && array_of_runtime_bound_p (TREE_TYPE (dest))) | |
771 | code = build_vec_init (dest, NULL_TREE, init, /*value-init*/false, | |
772 | /*from array*/1, tf_warning_or_error); | |
25ebb82a | 773 | else |
6ffbf87c | 774 | code = cp_build_init_expr (dest, init); |
25ebb82a RH |
775 | |
776 | return code; | |
777 | } | |
778 | ||
02777f20 PP |
779 | /* T is the initializer of a constexpr variable. Set CONSTRUCTOR_MUTABLE_POISON |
780 | for any CONSTRUCTOR within T that contains (directly or indirectly) a mutable | |
781 | member, thereby poisoning it so it can't be copied to another a constexpr | |
782 | variable or read during constexpr evaluation. */ | |
783 | ||
784 | static void | |
785 | poison_mutable_constructors (tree t) | |
786 | { | |
787 | if (TREE_CODE (t) != CONSTRUCTOR) | |
788 | return; | |
789 | ||
790 | if (cp_has_mutable_p (TREE_TYPE (t))) | |
791 | { | |
792 | CONSTRUCTOR_MUTABLE_POISON (t) = true; | |
793 | ||
794 | if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (t)) | |
795 | for (const constructor_elt &ce : *elts) | |
796 | poison_mutable_constructors (ce.value); | |
797 | } | |
798 | } | |
799 | ||
8d08fdba MS |
800 | /* Perform appropriate conversions on the initial value of a variable, |
801 | store it in the declaration DECL, | |
802 | and print any error messages that are appropriate. | |
803 | If the init is invalid, store an ERROR_MARK. | |
804 | ||
805 | C++: Note that INIT might be a TREE_LIST, which would mean that it is | |
806 | a base class initializer for some aggregate type, hopefully compatible | |
807 | with DECL. If INIT is a single element, and DECL is an aggregate | |
808 | type, we silently convert INIT into a TREE_LIST, allowing a constructor | |
809 | to be called. | |
810 | ||
811 | If INIT is a TREE_LIST and there is no constructor, turn INIT | |
812 | into a CONSTRUCTOR and use standard initialization techniques. | |
813 | Perhaps a warning should be generated? | |
814 | ||
25ebb82a RH |
815 | Returns code to be executed if initialization could not be performed |
816 | for static variable. In that case, caller must emit the code. */ | |
8d08fdba MS |
817 | |
818 | tree | |
9771b263 | 819 | store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) |
8d08fdba | 820 | { |
926ce8bd | 821 | tree value, type; |
8d08fdba MS |
822 | |
823 | /* If variable's type was invalidly declared, just ignore it. */ | |
824 | ||
825 | type = TREE_TYPE (decl); | |
826 | if (TREE_CODE (type) == ERROR_MARK) | |
827 | return NULL_TREE; | |
828 | ||
9e1e64ec | 829 | if (MAYBE_CLASS_TYPE_P (type)) |
8d08fdba | 830 | { |
6eabb241 | 831 | if (TREE_CODE (init) == TREE_LIST) |
8d08fdba | 832 | { |
a82e1a7d | 833 | error ("constructor syntax used, but no constructor declared " |
0cbd7506 | 834 | "for type %qT", type); |
09357846 | 835 | init = build_constructor_from_list (init_list_type_node, nreverse (init)); |
8d08fdba | 836 | } |
8d08fdba | 837 | } |
8d08fdba MS |
838 | |
839 | /* End of special C++ code. */ | |
840 | ||
fa2200cb JM |
841 | if (flags & LOOKUP_ALREADY_DIGESTED) |
842 | value = init; | |
843 | else | |
08c35030 BE |
844 | { |
845 | if (TREE_STATIC (decl)) | |
846 | flags |= LOOKUP_ALLOW_FLEXARRAY_INIT; | |
847 | /* Digest the specified initializer into an expression. */ | |
848 | value = digest_init_flags (type, init, flags, tf_warning_or_error); | |
849 | } | |
fa2200cb | 850 | |
bec1da64 MS |
851 | /* Look for braced array initializers for character arrays and |
852 | recursively convert them into STRING_CSTs. */ | |
853 | value = braced_lists_to_strings (type, value); | |
b5764229 | 854 | |
b5d0294e | 855 | current_ref_temp_count = 0; |
b25dd954 JM |
856 | value = extend_ref_init_temps (decl, value, cleanups); |
857 | ||
0e75e41f | 858 | /* In C++11 constant expression is a semantic, not syntactic, property. |
fa2200cb | 859 | In C++98, make sure that what we thought was a constant expression at |
c7a918f1 JJ |
860 | template definition time is still constant and otherwise perform this |
861 | as optimization, e.g. to fold SIZEOF_EXPRs in the initializer. */ | |
862 | if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl)) | |
fa2200cb JM |
863 | { |
864 | bool const_init; | |
e56f6629 | 865 | tree oldval = value; |
46812ec2 | 866 | if (DECL_DECLARED_CONSTEXPR_P (decl) |
8d46516a | 867 | || DECL_DECLARED_CONSTINIT_P (decl) |
53de8a7e | 868 | || (DECL_IN_AGGR_P (decl) |
752620be | 869 | && DECL_INITIALIZED_IN_CLASS_P (decl))) |
55e83c66 | 870 | { |
69bf1c7d MP |
871 | value = fold_non_dependent_expr (value, tf_warning_or_error, |
872 | /*manifestly_const_eval=*/true, | |
873 | decl); | |
8d46516a JM |
874 | if (value == error_mark_node) |
875 | ; | |
53de8a7e JJ |
876 | /* Diagnose a non-constant initializer for constexpr variable or |
877 | non-inline in-class-initialized static data member. */ | |
8d46516a JM |
878 | else if (!is_constant_expression (value)) |
879 | { | |
880 | /* Maybe we want to give this message for constexpr variables as | |
881 | well, but that will mean a lot of testsuite adjustment. */ | |
882 | if (DECL_DECLARED_CONSTINIT_P (decl)) | |
883 | error_at (location_of (decl), | |
884 | "%<constinit%> variable %qD does not have a " | |
885 | "constant initializer", decl); | |
886 | require_constant_expression (value); | |
887 | value = error_mark_node; | |
888 | } | |
55e83c66 | 889 | else |
8d46516a JM |
890 | { |
891 | value = maybe_constant_init (value, decl, true); | |
892 | ||
893 | /* In a template we might not have done the necessary | |
894 | transformations to make value actually constant, | |
895 | e.g. extend_ref_init_temps. */ | |
896 | if (!processing_template_decl | |
897 | && !TREE_CONSTANT (value)) | |
898 | { | |
899 | if (DECL_DECLARED_CONSTINIT_P (decl)) | |
900 | error_at (location_of (decl), | |
901 | "%<constinit%> variable %qD does not have a " | |
902 | "constant initializer", decl); | |
903 | value = cxx_constant_init (value, decl); | |
904 | } | |
905 | } | |
55e83c66 | 906 | } |
118cd6ba | 907 | else |
69bf1c7d MP |
908 | value = fold_non_dependent_init (value, tf_warning_or_error, |
909 | /*manifestly_const_eval=*/true, decl); | |
02777f20 | 910 | poison_mutable_constructors (value); |
fa2200cb JM |
911 | const_init = (reduced_constant_expression_p (value) |
912 | || error_operand_p (value)); | |
913 | DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init; | |
46b2baa7 | 914 | /* FIXME setting TREE_CONSTANT on refs breaks the back end. */ |
9f613f06 | 915 | if (!TYPE_REF_P (type)) |
46b2baa7 | 916 | TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl); |
e56f6629 | 917 | if (!const_init) |
8d46516a | 918 | value = oldval; |
fa2200cb | 919 | } |
8e007055 JJ |
920 | /* Don't fold initializers of automatic variables in constexpr functions, |
921 | that might fold away something that needs to be diagnosed at constexpr | |
922 | evaluation time. */ | |
923 | if (!current_function_decl | |
924 | || !DECL_DECLARED_CONSTEXPR_P (current_function_decl) | |
925 | || TREE_STATIC (decl)) | |
926 | value = cp_fully_fold_init (value); | |
fa2200cb | 927 | |
2166aeb3 MP |
928 | /* Handle aggregate NSDMI in non-constant initializers, too. */ |
929 | value = replace_placeholders (value, decl); | |
3e605b20 | 930 | |
3f0de4dd JM |
931 | /* A COMPOUND_LITERAL_P CONSTRUCTOR is the syntactic form; by the time we get |
932 | here it should have been digested into an actual value for the type. */ | |
933 | gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR | |
934 | || processing_template_decl | |
8861c807 | 935 | || VECTOR_TYPE_P (type) |
3f0de4dd JM |
936 | || !TREE_HAS_CONSTRUCTOR (value)); |
937 | ||
80439563 MM |
938 | /* If the initializer is not a constant, fill in DECL_INITIAL with |
939 | the bits that are constant, and then return an expression that | |
940 | will perform the dynamic initialization. */ | |
941 | if (value != error_mark_node | |
92a30040 | 942 | && !processing_template_decl |
80439563 | 943 | && (TREE_SIDE_EFFECTS (value) |
1d473b8b | 944 | || vla_type_p (type) |
deaae9d7 | 945 | || ! reduced_constant_expression_p (value))) |
89631a43 | 946 | return split_nonconstant_init (decl, value); |
b830c28b JM |
947 | |
948 | /* DECL may change value; purge caches. */ | |
bebabf70 | 949 | clear_cv_and_fold_caches (); |
b830c28b | 950 | |
80439563 MM |
951 | /* If the value is a constant, just put it in DECL_INITIAL. If DECL |
952 | is an automatic variable, the middle end will turn this into a | |
953 | dynamic initialization later. */ | |
8d08fdba MS |
954 | DECL_INITIAL (decl) = value; |
955 | return NULL_TREE; | |
956 | } | |
94e6e4c4 | 957 | |
8d08fdba | 958 | \f |
ed4f2c00 MP |
959 | /* Give diagnostic about narrowing conversions within { }, or as part of |
960 | a converted constant expression. If CONST_ONLY, only check | |
961 | constants. */ | |
09357846 | 962 | |
6a6bdc3d | 963 | bool |
f22f817c JM |
964 | check_narrowing (tree type, tree init, tsubst_flags_t complain, |
965 | bool const_only/*= false*/) | |
09357846 | 966 | { |
2d727f75 | 967 | tree ftype = unlowered_expr_type (init); |
09357846 JM |
968 | bool ok = true; |
969 | REAL_VALUE_TYPE d; | |
970 | ||
6a6bdc3d PC |
971 | if (((!warn_narrowing || !(complain & tf_warning)) |
972 | && cxx_dialect == cxx98) | |
ed4f2c00 MP |
973 | || !ARITHMETIC_TYPE_P (type) |
974 | /* Don't emit bogus warnings with e.g. value-dependent trees. */ | |
975 | || instantiation_dependent_expression_p (init)) | |
6a6bdc3d | 976 | return ok; |
35385f99 | 977 | |
77a30e9a JM |
978 | if (BRACE_ENCLOSED_INITIALIZER_P (init) |
979 | && TREE_CODE (type) == COMPLEX_TYPE) | |
980 | { | |
981 | tree elttype = TREE_TYPE (type); | |
320a9762 | 982 | if (CONSTRUCTOR_NELTS (init) > 0) |
6a6bdc3d PC |
983 | ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value, |
984 | complain); | |
77a30e9a | 985 | if (CONSTRUCTOR_NELTS (init) > 1) |
6a6bdc3d PC |
986 | ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value, |
987 | complain); | |
988 | return ok; | |
77a30e9a JM |
989 | } |
990 | ||
d417b4f5 MP |
991 | /* Even non-dependent expressions can still have template |
992 | codes like CAST_EXPR, so use *_non_dependent_expr to cope. */ | |
1595fe44 | 993 | init = fold_non_dependent_expr (init, complain, /*manifest*/true); |
d417b4f5 MP |
994 | if (init == error_mark_node) |
995 | return ok; | |
ed4f2c00 MP |
996 | |
997 | /* If we were asked to only check constants, return early. */ | |
998 | if (const_only && !TREE_CONSTANT (init)) | |
999 | return ok; | |
09357846 | 1000 | |
992931ba | 1001 | if (CP_INTEGRAL_TYPE_P (type) |
8861c807 | 1002 | && SCALAR_FLOAT_TYPE_P (ftype)) |
09357846 JM |
1003 | ok = false; |
1004 | else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype) | |
1005 | && CP_INTEGRAL_TYPE_P (type)) | |
1006 | { | |
5e23183b JM |
1007 | if (TREE_CODE (ftype) == ENUMERAL_TYPE) |
1008 | /* Check for narrowing based on the values of the enumeration. */ | |
1009 | ftype = ENUM_UNDERLYING_TYPE (ftype); | |
d7cfa314 JM |
1010 | if ((tree_int_cst_lt (TYPE_MAX_VALUE (type), |
1011 | TYPE_MAX_VALUE (ftype)) | |
1012 | || tree_int_cst_lt (TYPE_MIN_VALUE (ftype), | |
1013 | TYPE_MIN_VALUE (type))) | |
09357846 JM |
1014 | && (TREE_CODE (init) != INTEGER_CST |
1015 | || !int_fits_type_p (init, type))) | |
1016 | ok = false; | |
1017 | } | |
5d5dcc65 MP |
1018 | /* [dcl.init.list]#7.2: "from long double to double or float, or from |
1019 | double to float". */ | |
8861c807 BRF |
1020 | else if (SCALAR_FLOAT_TYPE_P (ftype) |
1021 | && SCALAR_FLOAT_TYPE_P (type)) | |
09357846 | 1022 | { |
b0420889 JJ |
1023 | if ((extended_float_type_p (ftype) || extended_float_type_p (type)) |
1024 | ? /* "from a floating-point type T to another floating-point type | |
1025 | whose floating-point conversion rank is neither greater than | |
1026 | nor equal to that of T". | |
1027 | So, it is ok if | |
1028 | cp_compare_floating_point_conversion_ranks (ftype, type) | |
1029 | returns -2 (type has greater conversion rank than ftype) | |
1030 | or [-1..1] (type has equal conversion rank as ftype, possibly | |
1031 | different subrank. Only do this if at least one of the | |
1032 | types is extended floating-point type, otherwise keep doing | |
1033 | what we did before (for the sake of non-standard | |
1034 | backend types). */ | |
1035 | cp_compare_floating_point_conversion_ranks (ftype, type) >= 2 | |
1036 | : ((same_type_p (ftype, long_double_type_node) | |
1037 | && (same_type_p (type, double_type_node) | |
1038 | || same_type_p (type, float_type_node))) | |
1039 | || (same_type_p (ftype, double_type_node) | |
1040 | && same_type_p (type, float_type_node)) | |
1041 | || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)))) | |
09357846 | 1042 | { |
09357846 JM |
1043 | if (TREE_CODE (init) == REAL_CST) |
1044 | { | |
72258929 JM |
1045 | /* Issue 703: Loss of precision is OK as long as the value is |
1046 | within the representable range of the new type. */ | |
1047 | REAL_VALUE_TYPE r; | |
09357846 | 1048 | d = TREE_REAL_CST (init); |
72258929 JM |
1049 | real_convert (&r, TYPE_MODE (type), &d); |
1050 | if (real_isinf (&r)) | |
1051 | ok = false; | |
09357846 | 1052 | } |
72258929 JM |
1053 | else |
1054 | ok = false; | |
09357846 JM |
1055 | } |
1056 | } | |
1057 | else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype) | |
8861c807 | 1058 | && SCALAR_FLOAT_TYPE_P (type)) |
09357846 JM |
1059 | { |
1060 | ok = false; | |
1061 | if (TREE_CODE (init) == INTEGER_CST) | |
1062 | { | |
1063 | d = real_value_from_int_cst (0, init); | |
1064 | if (exact_real_truncate (TYPE_MODE (type), &d)) | |
1065 | ok = true; | |
1066 | } | |
1067 | } | |
2806ecbd JM |
1068 | else if (TREE_CODE (type) == BOOLEAN_TYPE |
1069 | && (TYPE_PTR_P (ftype) || TYPE_PTRMEM_P (ftype))) | |
0ca22d02 MP |
1070 | /* C++20 P1957R2: converting from a pointer type or a pointer-to-member |
1071 | type to bool should be considered narrowing. This is a DR so is not | |
1072 | limited to C++20 only. */ | |
1073 | ok = false; | |
09357846 | 1074 | |
cda0a029 JM |
1075 | bool almost_ok = ok; |
1076 | if (!ok && !CONSTANT_CLASS_P (init) && (complain & tf_warning_or_error)) | |
1077 | { | |
1078 | tree folded = cp_fully_fold (init); | |
1079 | if (TREE_CONSTANT (folded) && check_narrowing (type, folded, tf_none)) | |
1080 | almost_ok = true; | |
1081 | } | |
1082 | ||
09357846 | 1083 | if (!ok) |
25339f10 | 1084 | { |
f9d0ca40 | 1085 | location_t loc = cp_expr_loc_or_input_loc (init); |
6a6bdc3d | 1086 | if (cxx_dialect == cxx98) |
cda0a029 JM |
1087 | { |
1088 | if (complain & tf_warning) | |
1089 | warning_at (loc, OPT_Wnarrowing, "narrowing conversion of %qE " | |
ed4f2c00 | 1090 | "from %qH to %qI is ill-formed in C++11", |
cda0a029 JM |
1091 | init, ftype, type); |
1092 | ok = true; | |
1093 | } | |
1094 | else if (!CONSTANT_CLASS_P (init)) | |
6a6bdc3d PC |
1095 | { |
1096 | if (complain & tf_warning_or_error) | |
1097 | { | |
097f82ec | 1098 | auto_diagnostic_group d; |
72f382fb PC |
1099 | if ((!almost_ok || pedantic) |
1100 | && pedwarn (loc, OPT_Wnarrowing, | |
ed4f2c00 | 1101 | "narrowing conversion of %qE from %qH to %qI", |
72f382fb PC |
1102 | init, ftype, type) |
1103 | && almost_ok) | |
cda0a029 JM |
1104 | inform (loc, " the expression has a constant value but is not " |
1105 | "a C++ constant-expression"); | |
6a6bdc3d PC |
1106 | ok = true; |
1107 | } | |
1108 | } | |
1109 | else if (complain & tf_error) | |
2821fc6b | 1110 | { |
f5322614 | 1111 | int savederrorcount = errorcount; |
1ec36bcd JM |
1112 | permerror_opt (loc, OPT_Wnarrowing, |
1113 | "narrowing conversion of %qE from %qH to %qI", | |
1114 | init, ftype, type); | |
f5322614 | 1115 | if (errorcount == savederrorcount) |
38920aec | 1116 | ok = true; |
2821fc6b | 1117 | } |
25339f10 | 1118 | } |
6a6bdc3d | 1119 | |
cda0a029 | 1120 | return ok; |
09357846 JM |
1121 | } |
1122 | ||
b04445d4 | 1123 | /* True iff TYPE is a C++20 "ordinary" character type. */ |
2d91f79d TH |
1124 | |
1125 | bool | |
1126 | ordinary_char_type_p (tree type) | |
1127 | { | |
1128 | type = TYPE_MAIN_VARIANT (type); | |
1129 | return (type == char_type_node | |
1130 | || type == signed_char_type_node | |
1131 | || type == unsigned_char_type_node); | |
1132 | } | |
1133 | ||
e6cc142a TG |
1134 | /* True iff the string literal INIT has a type suitable for initializing array |
1135 | TYPE. */ | |
1136 | ||
1137 | bool | |
1138 | array_string_literal_compatible_p (tree type, tree init) | |
1139 | { | |
1140 | tree to_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | |
1141 | tree from_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init))); | |
1142 | ||
1143 | if (to_char_type == from_char_type) | |
1144 | return true; | |
1145 | /* The array element type does not match the initializing string | |
1146 | literal element type; this is only allowed when both types are | |
1147 | ordinary character type. There are no string literals of | |
1148 | signed or unsigned char type in the language, but we can get | |
1149 | them internally from converting braced-init-lists to | |
1150 | STRING_CST. */ | |
1151 | if (ordinary_char_type_p (to_char_type) | |
1152 | && ordinary_char_type_p (from_char_type)) | |
1153 | return true; | |
567329fd MP |
1154 | |
1155 | /* P2513 (C++20/C++23): "an array of char or unsigned char may | |
1156 | be initialized by a UTF-8 string literal, or by such a string | |
1157 | literal enclosed in braces." */ | |
1158 | if (from_char_type == char8_type_node | |
1159 | && (to_char_type == char_type_node | |
1160 | || to_char_type == unsigned_char_type_node)) | |
1161 | return true; | |
1162 | ||
e6cc142a TG |
1163 | return false; |
1164 | } | |
1165 | ||
4038c495 GB |
1166 | /* Process the initializer INIT for a variable of type TYPE, emitting |
1167 | diagnostics for invalid initializers and converting the initializer as | |
1168 | appropriate. | |
8d08fdba | 1169 | |
4038c495 | 1170 | For aggregate types, it assumes that reshape_init has already run, thus the |
09357846 | 1171 | initializer will have the right shape (brace elision has been undone). |
8d08fdba | 1172 | |
a8c55cac JJ |
1173 | NESTED is non-zero iff we are being called for an element of a CONSTRUCTOR, |
1174 | 2 iff the element of a CONSTRUCTOR is inside another CONSTRUCTOR. */ | |
09357846 JM |
1175 | |
1176 | static tree | |
a8c55cac | 1177 | digest_init_r (tree type, tree init, int nested, int flags, |
754af126 | 1178 | tsubst_flags_t complain) |
8d08fdba MS |
1179 | { |
1180 | enum tree_code code = TREE_CODE (type); | |
8d08fdba | 1181 | |
97471c71 | 1182 | if (error_operand_p (init)) |
8d08fdba MS |
1183 | return error_mark_node; |
1184 | ||
4038c495 | 1185 | gcc_assert (init); |
b8b98c66 NS |
1186 | |
1187 | /* We must strip the outermost array type when completing the type, | |
1188 | because the its bounds might be incomplete at the moment. */ | |
a8c55cac | 1189 | if (!complete_type_or_maybe_complain (code == ARRAY_TYPE |
2d49bd6e PC |
1190 | ? TREE_TYPE (type) : type, NULL_TREE, |
1191 | complain)) | |
b8b98c66 | 1192 | return error_mark_node; |
c8094d83 | 1193 | |
f9d0ca40 | 1194 | location_t loc = cp_expr_loc_or_input_loc (init); |
15c40a3b DM |
1195 | |
1196 | tree stripped_init = init; | |
1197 | ||
43aae289 MP |
1198 | if (BRACE_ENCLOSED_INITIALIZER_P (init) |
1199 | && CONSTRUCTOR_IS_PAREN_INIT (init)) | |
1200 | flags |= LOOKUP_AGGREGATE_PAREN_INIT; | |
1201 | ||
4038c495 GB |
1202 | /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue |
1203 | (g++.old-deja/g++.law/casts2.C). */ | |
8d08fdba | 1204 | if (TREE_CODE (init) == NON_LVALUE_EXPR) |
15c40a3b | 1205 | stripped_init = TREE_OPERAND (init, 0); |
acfadf06 | 1206 | |
15c40a3b | 1207 | stripped_init = tree_strip_any_location_wrapper (stripped_init); |
dfd7fdca | 1208 | |
4038c495 GB |
1209 | /* Initialization of an array of chars from a string constant. The initializer |
1210 | can be optionally enclosed in braces, but reshape_init has already removed | |
1211 | them if they were present. */ | |
8d08fdba MS |
1212 | if (code == ARRAY_TYPE) |
1213 | { | |
05dd97db | 1214 | if (nested && !TYPE_DOMAIN (type)) |
a8c55cac | 1215 | /* C++ flexible array members have a null domain. */ |
08c35030 BE |
1216 | { |
1217 | if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT) | |
1218 | pedwarn (loc, OPT_Wpedantic, | |
1219 | "initialization of a flexible array member"); | |
1220 | else | |
1221 | { | |
1222 | if (complain & tf_error) | |
1223 | error_at (loc, "non-static initialization of" | |
1224 | " a flexible array member"); | |
1225 | return error_mark_node; | |
1226 | } | |
1227 | } | |
05dd97db | 1228 | |
4038c495 | 1229 | tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
7b019c19 | 1230 | if (char_type_p (typ1) |
dfd7fdca | 1231 | && TREE_CODE (stripped_init) == STRING_CST) |
8d08fdba | 1232 | { |
e6cc142a | 1233 | if (!array_string_literal_compatible_p (type, init)) |
8d08fdba | 1234 | { |
2d91f79d TH |
1235 | if (complain & tf_error) |
1236 | error_at (loc, "cannot initialize array of %qT from " | |
e6cc142a TG |
1237 | "a string literal with type array of %qT", |
1238 | typ1, | |
1239 | TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)))); | |
2d91f79d | 1240 | return error_mark_node; |
8d08fdba MS |
1241 | } |
1242 | ||
a8c55cac JJ |
1243 | if (nested == 2 && !TYPE_DOMAIN (type)) |
1244 | { | |
1245 | if (complain & tf_error) | |
1246 | error_at (loc, "initialization of flexible array member " | |
1247 | "in a nested context"); | |
1248 | return error_mark_node; | |
1249 | } | |
1250 | ||
5a68fae7 JM |
1251 | if (type != TREE_TYPE (init) |
1252 | && !variably_modified_type_p (type, NULL_TREE)) | |
7d510a82 PC |
1253 | { |
1254 | init = copy_node (init); | |
1255 | TREE_TYPE (init) = type; | |
dfd7fdca DM |
1256 | /* If we have a location wrapper, then also copy the wrapped |
1257 | node, and update the copy's type. */ | |
1258 | if (location_wrapper_p (init)) | |
1259 | { | |
1260 | stripped_init = copy_node (stripped_init); | |
1261 | TREE_OPERAND (init, 0) = stripped_init; | |
1262 | TREE_TYPE (stripped_init) = type; | |
1263 | } | |
7d510a82 | 1264 | } |
05dd97db | 1265 | if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type))) |
8d08fdba | 1266 | { |
7e9a3ad3 | 1267 | /* Not a flexible array member. */ |
926ce8bd | 1268 | int size = TREE_INT_CST_LOW (TYPE_SIZE (type)); |
8d08fdba MS |
1269 | size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; |
1270 | /* In C it is ok to subtract 1 from the length of the string | |
1271 | because it's ok to ignore the terminating null char that is | |
1272 | counted in the length of the constant, but in C++ this would | |
1273 | be invalid. */ | |
dfd7fdca | 1274 | if (size < TREE_STRING_LENGTH (stripped_init)) |
0a4b0aa1 | 1275 | { |
a9c697b8 MS |
1276 | permerror (loc, "initializer-string for %qT is too long", |
1277 | type); | |
0a4b0aa1 | 1278 | |
dfd7fdca DM |
1279 | init = build_string (size, |
1280 | TREE_STRING_POINTER (stripped_init)); | |
0a4b0aa1 BE |
1281 | TREE_TYPE (init) = type; |
1282 | } | |
8d08fdba | 1283 | } |
4038c495 | 1284 | return init; |
8d08fdba MS |
1285 | } |
1286 | } | |
1287 | ||
3c955a04 | 1288 | /* Handle scalar types (including conversions) and references. */ |
dfd7fdca | 1289 | if ((code != COMPLEX_TYPE || BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) |
b8063b29 | 1290 | && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE)) |
6524147c | 1291 | { |
43aae289 MP |
1292 | /* Narrowing is OK when initializing an aggregate from |
1293 | a parenthesized list. */ | |
1294 | if (nested && !(flags & LOOKUP_AGGREGATE_PAREN_INIT)) | |
2410819b | 1295 | flags |= LOOKUP_NO_NARROWING; |
e57d93c6 | 1296 | init = convert_for_initialization (0, type, init, flags, |
2f5b91f5 | 1297 | ICR_INIT, NULL_TREE, 0, |
754af126 | 1298 | complain); |
6524147c OW |
1299 | |
1300 | return init; | |
1301 | } | |
4038c495 GB |
1302 | |
1303 | /* Come here only for aggregates: records, arrays, unions, complex numbers | |
1304 | and vectors. */ | |
a8c55cac | 1305 | gcc_assert (code == ARRAY_TYPE |
b55b02ea | 1306 | || VECTOR_TYPE_P (type) |
a8c55cac JJ |
1307 | || code == RECORD_TYPE |
1308 | || code == UNION_TYPE | |
7e231b2c | 1309 | || code == OPAQUE_TYPE |
a8c55cac | 1310 | || code == COMPLEX_TYPE); |
4038c495 | 1311 | |
d5449acf JM |
1312 | /* "If T is a class type and the initializer list has a single |
1313 | element of type cv U, where U is T or a class derived from T, | |
1314 | the object is initialized from that element." */ | |
15f4769a | 1315 | if (cxx_dialect >= cxx11 |
dfd7fdca | 1316 | && BRACE_ENCLOSED_INITIALIZER_P (stripped_init) |
885035ea | 1317 | && !CONSTRUCTOR_IS_DESIGNATED_INIT (stripped_init) |
dfd7fdca | 1318 | && CONSTRUCTOR_NELTS (stripped_init) == 1 |
7457279b JM |
1319 | && ((CLASS_TYPE_P (type) && !CLASSTYPE_NON_AGGREGATE (type)) |
1320 | || VECTOR_TYPE_P (type))) | |
d5449acf | 1321 | { |
dfd7fdca | 1322 | tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value; |
d5449acf | 1323 | if (reference_related_p (type, TREE_TYPE (elt))) |
bf8c1b11 MP |
1324 | { |
1325 | /* In C++17, aggregates can have bases, thus participate in | |
1326 | aggregate initialization. In the following case: | |
1327 | ||
1328 | struct B { int c; }; | |
1329 | struct D : B { }; | |
1330 | D d{{D{{42}}}}; | |
1331 | ||
1332 | there's an extra set of braces, so the D temporary initializes | |
1333 | the first element of d, which is the B base subobject. The base | |
1334 | of type B is copy-initialized from the D temporary, causing | |
1335 | object slicing. */ | |
0c7bce0a | 1336 | tree field = next_aggregate_field (TYPE_FIELDS (type)); |
bf8c1b11 MP |
1337 | if (field && DECL_FIELD_IS_BASE (field)) |
1338 | { | |
1339 | if (warning_at (loc, 0, "initializing a base class of type %qT " | |
1340 | "results in object slicing", TREE_TYPE (field))) | |
1341 | inform (loc, "remove %<{ }%> around initializer"); | |
1342 | } | |
15f4769a | 1343 | else if (flag_checking) |
bf8c1b11 MP |
1344 | /* We should have fixed this in reshape_init. */ |
1345 | gcc_unreachable (); | |
1346 | } | |
d5449acf JM |
1347 | } |
1348 | ||
4f6bc28f JM |
1349 | if (SIMPLE_TARGET_EXPR_P (stripped_init)) |
1350 | stripped_init = TARGET_EXPR_INITIAL (stripped_init); | |
1351 | ||
dfd7fdca | 1352 | if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init) |
fc94bfc5 | 1353 | && !TYPE_NON_AGGREGATE_CLASS (type)) |
08c35030 BE |
1354 | return process_init_constructor (type, stripped_init, nested, flags, |
1355 | complain); | |
4038c495 | 1356 | else |
8d08fdba | 1357 | { |
dfd7fdca | 1358 | if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE) |
8d08fdba | 1359 | { |
754af126 | 1360 | if (complain & tf_error) |
acfadf06 PC |
1361 | error_at (loc, "cannot initialize aggregate of type %qT with " |
1362 | "a compound literal", type); | |
8d08fdba | 1363 | |
4038c495 GB |
1364 | return error_mark_node; |
1365 | } | |
8e76c2bf | 1366 | |
a8c55cac | 1367 | if (code == ARRAY_TYPE |
dfd7fdca | 1368 | && !BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) |
8e76c2bf | 1369 | { |
c6569cd0 JM |
1370 | /* Allow the result of build_array_copy and of |
1371 | build_value_init_noctor. */ | |
dfd7fdca DM |
1372 | if ((TREE_CODE (stripped_init) == VEC_INIT_EXPR |
1373 | || TREE_CODE (stripped_init) == CONSTRUCTOR) | |
d5f4eddd JM |
1374 | && (same_type_ignoring_top_level_qualifiers_p |
1375 | (type, TREE_TYPE (init)))) | |
1376 | return init; | |
1377 | ||
754af126 | 1378 | if (complain & tf_error) |
acfadf06 PC |
1379 | error_at (loc, "array must be initialized with a brace-enclosed" |
1380 | " initializer"); | |
8e76c2bf MS |
1381 | return error_mark_node; |
1382 | } | |
1383 | ||
4038c495 | 1384 | return convert_for_initialization (NULL_TREE, type, init, |
e57d93c6 | 1385 | flags, |
2f5b91f5 | 1386 | ICR_INIT, NULL_TREE, 0, |
754af126 | 1387 | complain); |
8d08fdba | 1388 | } |
4038c495 GB |
1389 | } |
1390 | ||
09357846 | 1391 | tree |
754af126 | 1392 | digest_init (tree type, tree init, tsubst_flags_t complain) |
09357846 | 1393 | { |
a8c55cac | 1394 | return digest_init_r (type, init, 0, LOOKUP_IMPLICIT, complain); |
e57d93c6 JM |
1395 | } |
1396 | ||
1397 | tree | |
0bdc4c1c | 1398 | digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain) |
e57d93c6 | 1399 | { |
a8c55cac | 1400 | return digest_init_r (type, init, 0, flags, complain); |
09357846 | 1401 | } |
f4cd9c51 | 1402 | |
1b661f3f MP |
1403 | /* Return true if SUBOB initializes the same object as FULL_EXPR. |
1404 | For instance: | |
1405 | ||
1406 | A a = A{}; // initializer | |
1407 | A a = (A{}); // initializer | |
1408 | A a = (1, A{}); // initializer | |
1409 | A a = true ? A{} : A{}; // initializer | |
1410 | auto x = A{}.x; // temporary materialization | |
1411 | auto x = foo(A{}); // temporary materialization | |
1412 | ||
1413 | FULL_EXPR is the whole expression, SUBOB is its TARGET_EXPR subobject. */ | |
1414 | ||
1415 | static bool | |
1416 | potential_prvalue_result_of (tree subob, tree full_expr) | |
1417 | { | |
1418 | if (subob == full_expr) | |
1419 | return true; | |
1420 | else if (TREE_CODE (full_expr) == TARGET_EXPR) | |
1421 | { | |
1422 | tree init = TARGET_EXPR_INITIAL (full_expr); | |
1423 | if (TREE_CODE (init) == COND_EXPR) | |
1424 | return (potential_prvalue_result_of (subob, TREE_OPERAND (init, 1)) | |
1425 | || potential_prvalue_result_of (subob, TREE_OPERAND (init, 2))); | |
1426 | else if (TREE_CODE (init) == COMPOUND_EXPR) | |
1427 | return potential_prvalue_result_of (subob, TREE_OPERAND (init, 1)); | |
1428 | /* ??? I don't know if this can be hit. */ | |
1429 | else if (TREE_CODE (init) == PAREN_EXPR) | |
1430 | { | |
1431 | gcc_checking_assert (false); | |
1432 | return potential_prvalue_result_of (subob, TREE_OPERAND (init, 0)); | |
1433 | } | |
1434 | } | |
1435 | return false; | |
1436 | } | |
1437 | ||
1438 | /* Callback to replace PLACEHOLDER_EXPRs in a TARGET_EXPR (which isn't used | |
1439 | in the context of guaranteed copy elision). */ | |
1440 | ||
1441 | static tree | |
1442 | replace_placeholders_for_class_temp_r (tree *tp, int *, void *data) | |
1443 | { | |
1444 | tree t = *tp; | |
1445 | tree full_expr = *static_cast<tree *>(data); | |
1446 | ||
1447 | /* We're looking for a TARGET_EXPR nested in the whole expression. */ | |
1448 | if (TREE_CODE (t) == TARGET_EXPR | |
1449 | && !potential_prvalue_result_of (t, full_expr)) | |
1450 | { | |
1451 | tree init = TARGET_EXPR_INITIAL (t); | |
1452 | while (TREE_CODE (init) == COMPOUND_EXPR) | |
1453 | init = TREE_OPERAND (init, 1); | |
1454 | if (TREE_CODE (init) == CONSTRUCTOR | |
1455 | && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)) | |
1456 | { | |
1457 | tree obj = TARGET_EXPR_SLOT (t); | |
1458 | replace_placeholders (init, obj); | |
1459 | /* We should have dealt with all PLACEHOLDER_EXPRs. */ | |
1460 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = false; | |
1461 | gcc_checking_assert (!find_placeholders (init)); | |
1462 | } | |
1463 | } | |
1464 | ||
1465 | return NULL_TREE; | |
1466 | } | |
1467 | ||
f4cd9c51 PC |
1468 | /* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */ |
1469 | tree | |
9fb82e65 | 1470 | digest_nsdmi_init (tree decl, tree init, tsubst_flags_t complain) |
f4cd9c51 PC |
1471 | { |
1472 | gcc_assert (TREE_CODE (decl) == FIELD_DECL); | |
1473 | ||
ebcf592c | 1474 | tree type = TREE_TYPE (decl); |
6fcb7ebb JJ |
1475 | if (DECL_BIT_FIELD_TYPE (decl)) |
1476 | type = DECL_BIT_FIELD_TYPE (decl); | |
f4cd9c51 PC |
1477 | int flags = LOOKUP_IMPLICIT; |
1478 | if (DIRECT_LIST_INIT_P (init)) | |
8a26547b JM |
1479 | { |
1480 | flags = LOOKUP_NORMAL; | |
1481 | complain |= tf_no_cleanup; | |
1482 | } | |
ebcf592c PC |
1483 | if (BRACE_ENCLOSED_INITIALIZER_P (init) |
1484 | && CP_AGGREGATE_TYPE_P (type)) | |
9fb82e65 JM |
1485 | init = reshape_init (type, init, complain); |
1486 | init = digest_init_flags (type, init, flags, complain); | |
6ffbf87c | 1487 | set_target_expr_eliding (init); |
1b661f3f MP |
1488 | |
1489 | /* We may have temporary materialization in a NSDMI, if the initializer | |
1490 | has something like A{} in it. Digesting the {} could have introduced | |
1491 | a PLACEHOLDER_EXPR referring to A. Now that we've got a TARGET_EXPR, | |
1492 | we have an object we can refer to. The reason we bother doing this | |
1493 | here is for code like | |
1494 | ||
1495 | struct A { | |
1496 | int x; | |
1497 | int y = x; | |
1498 | }; | |
1499 | ||
1500 | struct B { | |
1501 | int x = 0; | |
1502 | int y = A{x}.y; // #1 | |
1503 | }; | |
1504 | ||
1505 | where in #1 we don't want to end up with two PLACEHOLDER_EXPRs for | |
1506 | different types on the same level in a {} when lookup_placeholder | |
1507 | wouldn't find a named object for the PLACEHOLDER_EXPR for A. Note, | |
1508 | temporary materialization does not occur when initializing an object | |
1509 | from a prvalue of the same type, therefore we must not replace the | |
1510 | placeholder with a temporary object so that it can be elided. */ | |
1511 | cp_walk_tree (&init, replace_placeholders_for_class_temp_r, &init, | |
1512 | nullptr); | |
1513 | ||
f4cd9c51 PC |
1514 | return init; |
1515 | } | |
4038c495 GB |
1516 | \f |
1517 | /* Set of flags used within process_init_constructor to describe the | |
1518 | initializers. */ | |
1519 | #define PICFLAG_ERRONEOUS 1 | |
1520 | #define PICFLAG_NOT_ALL_CONSTANT 2 | |
1521 | #define PICFLAG_NOT_ALL_SIMPLE 4 | |
dd5593fc | 1522 | #define PICFLAG_SIDE_EFFECTS 8 |
e948436e | 1523 | #define PICFLAG_VEC_INIT 16 |
4038c495 GB |
1524 | |
1525 | /* Given an initializer INIT, return the flag (PICFLAG_*) which better | |
1526 | describe it. */ | |
1527 | ||
1528 | static int | |
1529 | picflag_from_initializer (tree init) | |
1530 | { | |
1531 | if (init == error_mark_node) | |
1532 | return PICFLAG_ERRONEOUS; | |
1533 | else if (!TREE_CONSTANT (init)) | |
dd5593fc JM |
1534 | { |
1535 | if (TREE_SIDE_EFFECTS (init)) | |
1536 | return PICFLAG_SIDE_EFFECTS; | |
1537 | else | |
1538 | return PICFLAG_NOT_ALL_CONSTANT; | |
1539 | } | |
4038c495 GB |
1540 | else if (!initializer_constant_valid_p (init, TREE_TYPE (init))) |
1541 | return PICFLAG_NOT_ALL_SIMPLE; | |
1542 | return 0; | |
1543 | } | |
8d08fdba | 1544 | |
41852027 JM |
1545 | /* Adjust INIT for going into a CONSTRUCTOR. */ |
1546 | ||
1547 | static tree | |
08c35030 BE |
1548 | massage_init_elt (tree type, tree init, int nested, int flags, |
1549 | tsubst_flags_t complain) | |
41852027 | 1550 | { |
43aae289 MP |
1551 | int new_flags = LOOKUP_IMPLICIT; |
1552 | if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT) | |
1553 | new_flags |= LOOKUP_ALLOW_FLEXARRAY_INIT; | |
1554 | if (flags & LOOKUP_AGGREGATE_PAREN_INIT) | |
1555 | new_flags |= LOOKUP_AGGREGATE_PAREN_INIT; | |
1556 | init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain); | |
41852027 | 1557 | /* When we defer constant folding within a statement, we may want to |
f0530882 MP |
1558 | defer this folding as well. Don't call this on CONSTRUCTORs because |
1559 | their elements have already been folded, and we must avoid folding | |
1560 | the result of get_nsdmi. */ | |
1561 | if (TREE_CODE (init) != CONSTRUCTOR) | |
1562 | { | |
1563 | tree t = fold_non_dependent_init (init, complain); | |
1564 | if (TREE_CONSTANT (t)) | |
1565 | init = t; | |
6ffbf87c | 1566 | set_target_expr_eliding (init); |
f0530882 | 1567 | } |
41852027 JM |
1568 | return init; |
1569 | } | |
1570 | ||
4038c495 | 1571 | /* Subroutine of process_init_constructor, which will process an initializer |
d732e98f KH |
1572 | INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*) |
1573 | which describe the initializers. */ | |
8d08fdba | 1574 | |
4038c495 | 1575 | static int |
08c35030 | 1576 | process_init_constructor_array (tree type, tree init, int nested, int flags, |
754af126 | 1577 | tsubst_flags_t complain) |
4038c495 GB |
1578 | { |
1579 | unsigned HOST_WIDE_INT i, len = 0; | |
08c35030 | 1580 | int picflags = 0; |
4038c495 GB |
1581 | bool unbounded = false; |
1582 | constructor_elt *ce; | |
9771b263 | 1583 | vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init); |
4038c495 GB |
1584 | |
1585 | gcc_assert (TREE_CODE (type) == ARRAY_TYPE | |
b55b02ea | 1586 | || VECTOR_TYPE_P (type)); |
4038c495 GB |
1587 | |
1588 | if (TREE_CODE (type) == ARRAY_TYPE) | |
8d08fdba | 1589 | { |
05dd97db | 1590 | /* C++ flexible array members have a null domain. */ |
4038c495 | 1591 | tree domain = TYPE_DOMAIN (type); |
05dd97db MS |
1592 | if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain))) |
1593 | len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain)) | |
1594 | - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1, | |
807e902e KZ |
1595 | TYPE_PRECISION (TREE_TYPE (domain)), |
1596 | TYPE_SIGN (TREE_TYPE (domain))).to_uhwi (); | |
4038c495 GB |
1597 | else |
1598 | unbounded = true; /* Take as many as there are. */ | |
a8c55cac JJ |
1599 | |
1600 | if (nested == 2 && !domain && !vec_safe_is_empty (v)) | |
1601 | { | |
1602 | if (complain & tf_error) | |
f9d0ca40 | 1603 | error_at (cp_expr_loc_or_input_loc (init), |
a8c55cac JJ |
1604 | "initialization of flexible array member " |
1605 | "in a nested context"); | |
1606 | return PICFLAG_ERRONEOUS; | |
1607 | } | |
8d08fdba | 1608 | } |
4038c495 GB |
1609 | else |
1610 | /* Vectors are like simple fixed-size arrays. */ | |
928686b1 | 1611 | unbounded = !TYPE_VECTOR_SUBPARTS (type).is_constant (&len); |
8d08fdba | 1612 | |
25357d1e | 1613 | /* There must not be more initializers than needed. */ |
9771b263 | 1614 | if (!unbounded && vec_safe_length (v) > len) |
754af126 PC |
1615 | { |
1616 | if (complain & tf_error) | |
1617 | error ("too many initializers for %qT", type); | |
1618 | else | |
1619 | return PICFLAG_ERRONEOUS; | |
1620 | } | |
4038c495 | 1621 | |
9771b263 | 1622 | FOR_EACH_VEC_SAFE_ELT (v, i, ce) |
8d08fdba | 1623 | { |
1c97d579 | 1624 | if (!ce->index) |
4038c495 | 1625 | ce->index = size_int (i); |
1c97d579 PC |
1626 | else if (!check_array_designated_initializer (ce, i)) |
1627 | ce->index = error_mark_node; | |
4038c495 | 1628 | gcc_assert (ce->value); |
a8c55cac | 1629 | ce->value |
08c35030 BE |
1630 | = massage_init_elt (TREE_TYPE (type), ce->value, nested, flags, |
1631 | complain); | |
d22c8596 | 1632 | |
da0c07b2 JM |
1633 | gcc_checking_assert |
1634 | (ce->value == error_mark_node | |
1635 | || (same_type_ignoring_top_level_qualifiers_p | |
1636 | (strip_array_types (TREE_TYPE (type)), | |
1637 | strip_array_types (TREE_TYPE (ce->value))))); | |
dc26f471 | 1638 | |
08c35030 | 1639 | picflags |= picflag_from_initializer (ce->value); |
eb03e424 JJ |
1640 | /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer |
1641 | CONSTRUCTOR. */ | |
1642 | if (TREE_CODE (ce->value) == CONSTRUCTOR | |
1643 | && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value)) | |
1644 | { | |
1645 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
1646 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0; | |
1647 | } | |
8d08fdba MS |
1648 | } |
1649 | ||
114bf260 JM |
1650 | /* No more initializers. If the array is unbounded, we are done. Otherwise, |
1651 | we must add initializers ourselves. */ | |
1652 | if (!unbounded) | |
1653 | for (; i < len; ++i) | |
1654 | { | |
1655 | tree next; | |
1656 | ||
1657 | if (type_build_ctor_call (TREE_TYPE (type))) | |
1658 | { | |
1659 | /* If this type needs constructors run for default-initialization, | |
1660 | we can't rely on the back end to do it for us, so make the | |
3bc63227 | 1661 | initialization explicit by list-initializing from T{}. */ |
114bf260 | 1662 | next = build_constructor (init_list_type_node, NULL); |
08c35030 BE |
1663 | next = massage_init_elt (TREE_TYPE (type), next, nested, flags, |
1664 | complain); | |
114bf260 JM |
1665 | if (initializer_zerop (next)) |
1666 | /* The default zero-initialization is fine for us; don't | |
1667 | add anything to the CONSTRUCTOR. */ | |
1668 | next = NULL_TREE; | |
1669 | } | |
1670 | else if (!zero_init_p (TREE_TYPE (type))) | |
1671 | next = build_zero_init (TREE_TYPE (type), | |
1672 | /*nelts=*/NULL_TREE, | |
1673 | /*static_storage_p=*/false); | |
1674 | else | |
1675 | /* The default zero-initialization is fine for us; don't | |
1676 | add anything to the CONSTRUCTOR. */ | |
1677 | next = NULL_TREE; | |
1678 | ||
1679 | if (next) | |
1680 | { | |
e948436e | 1681 | if (next != error_mark_node |
307193b8 | 1682 | && (initializer_constant_valid_p (next, TREE_TYPE (next)) |
e948436e JM |
1683 | != null_pointer_node)) |
1684 | { | |
1685 | /* Use VEC_INIT_EXPR for non-constant initialization of | |
1686 | trailing elements with no explicit initializers. */ | |
1687 | picflags |= PICFLAG_VEC_INIT; | |
1688 | break; | |
1689 | } | |
1690 | ||
1691 | picflags |= picflag_from_initializer (next); | |
eb03e424 JJ |
1692 | /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer |
1693 | CONSTRUCTOR. */ | |
1694 | if (TREE_CODE (next) == CONSTRUCTOR | |
1695 | && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next)) | |
1696 | { | |
1697 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
1698 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0; | |
1699 | } | |
e948436e | 1700 | if (len > i+1) |
307193b8 JM |
1701 | { |
1702 | tree range = build2 (RANGE_EXPR, size_type_node, | |
1703 | build_int_cst (size_type_node, i), | |
1704 | build_int_cst (size_type_node, len - 1)); | |
1705 | CONSTRUCTOR_APPEND_ELT (v, range, next); | |
1706 | break; | |
1707 | } | |
1708 | else | |
1709 | CONSTRUCTOR_APPEND_ELT (v, size_int (i), next); | |
114bf260 | 1710 | } |
307193b8 JM |
1711 | else |
1712 | /* Don't bother checking all the other elements. */ | |
1713 | break; | |
114bf260 | 1714 | } |
4038c495 GB |
1715 | |
1716 | CONSTRUCTOR_ELTS (init) = v; | |
08c35030 | 1717 | return picflags; |
8d08fdba | 1718 | } |
8d08fdba | 1719 | |
4038c495 GB |
1720 | /* Subroutine of process_init_constructor, which will process an initializer |
1721 | INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe | |
1722 | the initializers. */ | |
8d08fdba | 1723 | |
4038c495 | 1724 | static int |
08c35030 | 1725 | process_init_constructor_record (tree type, tree init, int nested, int flags, |
754af126 | 1726 | tsubst_flags_t complain) |
8d08fdba | 1727 | { |
9771b263 | 1728 | vec<constructor_elt, va_gc> *v = NULL; |
4038c495 | 1729 | tree field; |
3e605b20 | 1730 | int skipped = 0; |
4038c495 GB |
1731 | |
1732 | gcc_assert (TREE_CODE (type) == RECORD_TYPE); | |
1733 | gcc_assert (!CLASSTYPE_VBASECLASSES (type)); | |
1734 | gcc_assert (!TYPE_BINFO (type) | |
7b936140 | 1735 | || cxx_dialect >= cxx17 |
4038c495 GB |
1736 | || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type))); |
1737 | gcc_assert (!TYPE_POLYMORPHIC_P (type)); | |
1738 | ||
3e605b20 | 1739 | restart: |
08c35030 | 1740 | int picflags = 0; |
3e605b20 | 1741 | unsigned HOST_WIDE_INT idx = 0; |
d68ddd2b | 1742 | int designator_skip = -1; |
4038c495 GB |
1743 | /* Generally, we will always have an index for each initializer (which is |
1744 | a FIELD_DECL, put by reshape_init), but compound literals don't go trough | |
1745 | reshape_init. So we need to handle both cases. */ | |
910ad8de | 1746 | for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) |
8d08fdba | 1747 | { |
4038c495 | 1748 | tree next; |
8d08fdba | 1749 | |
ec2416b5 JM |
1750 | if (TREE_CODE (field) != FIELD_DECL |
1751 | || (DECL_ARTIFICIAL (field) | |
7b936140 | 1752 | && !(cxx_dialect >= cxx17 && DECL_FIELD_IS_BASE (field)))) |
4038c495 GB |
1753 | continue; |
1754 | ||
7c30b12a PC |
1755 | if (DECL_UNNAMED_BIT_FIELD (field)) |
1756 | continue; | |
1757 | ||
2d727f75 | 1758 | /* If this is a bitfield, first convert to the declared type. */ |
f1fc27b6 | 1759 | tree fldtype = TREE_TYPE (field); |
2d727f75 | 1760 | if (DECL_BIT_FIELD_TYPE (field)) |
f1fc27b6 JM |
1761 | fldtype = DECL_BIT_FIELD_TYPE (field); |
1762 | if (fldtype == error_mark_node) | |
e765a228 | 1763 | return PICFLAG_ERRONEOUS; |
2d727f75 | 1764 | |
d68ddd2b | 1765 | next = NULL_TREE; |
aaa1b10f | 1766 | if (idx < CONSTRUCTOR_NELTS (init)) |
8d08fdba | 1767 | { |
9771b263 | 1768 | constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx]; |
4038c495 | 1769 | if (ce->index) |
8d08fdba | 1770 | { |
4038c495 GB |
1771 | /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The |
1772 | latter case can happen in templates where lookup has to be | |
1773 | deferred. */ | |
1774 | gcc_assert (TREE_CODE (ce->index) == FIELD_DECL | |
9dc6f476 | 1775 | || identifier_p (ce->index)); |
d68ddd2b JJ |
1776 | if (ce->index == field || ce->index == DECL_NAME (field)) |
1777 | next = ce->value; | |
d68ddd2b | 1778 | else |
e135a637 | 1779 | { |
d68ddd2b JJ |
1780 | ce = NULL; |
1781 | if (designator_skip == -1) | |
1782 | designator_skip = 1; | |
e135a637 | 1783 | } |
8d08fdba | 1784 | } |
d68ddd2b JJ |
1785 | else |
1786 | { | |
1787 | designator_skip = 0; | |
1788 | next = ce->value; | |
1789 | } | |
e6267549 | 1790 | |
d68ddd2b JJ |
1791 | if (ce) |
1792 | { | |
1793 | gcc_assert (ce->value); | |
f1fc27b6 | 1794 | next = massage_init_elt (fldtype, next, nested, flags, complain); |
6ffbf87c JM |
1795 | /* We can't actually elide the temporary when initializing a |
1796 | potentially-overlapping field from a function that returns by | |
1797 | value. */ | |
1798 | if (ce->index | |
1799 | && TREE_CODE (next) == TARGET_EXPR | |
1800 | && unsafe_copy_elision_p (ce->index, next)) | |
1801 | TARGET_EXPR_ELIDING_P (next) = false; | |
d68ddd2b JJ |
1802 | ++idx; |
1803 | } | |
4038c495 | 1804 | } |
30da2906 MP |
1805 | if (next == error_mark_node) |
1806 | /* We skip initializers for empty bases/fields, so skipping an invalid | |
1807 | one could make us accept invalid code. */ | |
1808 | return PICFLAG_ERRONEOUS; | |
1809 | else if (next) | |
d68ddd2b | 1810 | /* Already handled above. */; |
3e605b20 JM |
1811 | else if (DECL_INITIAL (field)) |
1812 | { | |
1813 | if (skipped > 0) | |
1814 | { | |
1815 | /* We're using an NSDMI past a field with implicit | |
1816 | zero-init. Go back and make it explicit. */ | |
1817 | skipped = -1; | |
1818 | vec_safe_truncate (v, 0); | |
1819 | goto restart; | |
1820 | } | |
1821 | /* C++14 aggregate NSDMI. */ | |
9fb82e65 | 1822 | next = get_nsdmi (field, /*ctor*/false, complain); |
570f86f9 JJ |
1823 | if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) |
1824 | && find_placeholders (next)) | |
1825 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
3e605b20 | 1826 | } |
f1fc27b6 | 1827 | else if (type_build_ctor_call (fldtype)) |
4038c495 GB |
1828 | { |
1829 | /* If this type needs constructors run for | |
3b426391 | 1830 | default-initialization, we can't rely on the back end to do it |
4038c495 GB |
1831 | for us, so build up TARGET_EXPRs. If the type in question is |
1832 | a class, just build one up; if it's an array, recurse. */ | |
4c9b3895 | 1833 | next = build_constructor (init_list_type_node, NULL); |
f1fc27b6 | 1834 | next = massage_init_elt (fldtype, next, nested, flags, complain); |
6ffbf87c JM |
1835 | if (TREE_CODE (next) == TARGET_EXPR |
1836 | && unsafe_copy_elision_p (field, next)) | |
1837 | TARGET_EXPR_ELIDING_P (next) = false; | |
4038c495 GB |
1838 | |
1839 | /* Warn when some struct elements are implicitly initialized. */ | |
450bfd7d | 1840 | if ((complain & tf_warning) |
814299a9 | 1841 | && !cp_unevaluated_operand |
450bfd7d | 1842 | && !EMPTY_CONSTRUCTOR_P (init)) |
c69c2835 PC |
1843 | warning (OPT_Wmissing_field_initializers, |
1844 | "missing initializer for member %qD", field); | |
4038c495 GB |
1845 | } |
1846 | else | |
1847 | { | |
9f613f06 | 1848 | if (TYPE_REF_P (fldtype)) |
754af126 PC |
1849 | { |
1850 | if (complain & tf_error) | |
c69c2835 | 1851 | error ("member %qD is uninitialized reference", field); |
754af126 PC |
1852 | else |
1853 | return PICFLAG_ERRONEOUS; | |
1854 | } | |
7e9a3ad3 | 1855 | else if (CLASSTYPE_REF_FIELDS_NEED_INIT (fldtype)) |
754af126 PC |
1856 | { |
1857 | if (complain & tf_error) | |
c69c2835 | 1858 | error ("member %qD with uninitialized reference fields", field); |
754af126 PC |
1859 | else |
1860 | return PICFLAG_ERRONEOUS; | |
1861 | } | |
e0737c20 JM |
1862 | /* Do nothing for flexible array members since they need not have any |
1863 | elements. Don't worry about 'skipped' because a flexarray has to | |
1864 | be the last field. */ | |
1865 | else if (TREE_CODE (fldtype) == ARRAY_TYPE && !TYPE_DOMAIN (fldtype)) | |
1866 | continue; | |
4038c495 GB |
1867 | |
1868 | /* Warn when some struct elements are implicitly initialized | |
e0737c20 JM |
1869 | to zero. */ |
1870 | if ((complain & tf_warning) | |
814299a9 | 1871 | && !cp_unevaluated_operand |
b1ae46bd MP |
1872 | && !EMPTY_CONSTRUCTOR_P (init) |
1873 | && !is_really_empty_class (fldtype, /*ignore_vptr*/false)) | |
c69c2835 PC |
1874 | warning (OPT_Wmissing_field_initializers, |
1875 | "missing initializer for member %qD", field); | |
4038c495 | 1876 | |
a9ed1829 JJ |
1877 | if (!zero_init_p (fldtype) || skipped < 0) |
1878 | { | |
1879 | if (TYPE_REF_P (fldtype)) | |
1880 | next = build_zero_cst (fldtype); | |
1881 | else | |
1882 | next = build_zero_init (fldtype, /*nelts=*/NULL_TREE, | |
1883 | /*static_storage_p=*/false); | |
1884 | } | |
e6267549 | 1885 | else |
3e605b20 JM |
1886 | { |
1887 | /* The default zero-initialization is fine for us; don't | |
1888 | add anything to the CONSTRUCTOR. */ | |
1889 | skipped = 1; | |
1890 | continue; | |
1891 | } | |
8d08fdba | 1892 | } |
4038c495 | 1893 | |
a4dfd0f0 | 1894 | if (is_empty_field (field) |
7b45322a JM |
1895 | && !TREE_SIDE_EFFECTS (next)) |
1896 | /* Don't add trivial initialization of an empty base/field to the | |
1897 | constructor, as they might not be ordered the way the back-end | |
1898 | expects. */ | |
1899 | continue; | |
1900 | ||
2d727f75 | 1901 | /* If this is a bitfield, now convert to the lowered type. */ |
f1fc27b6 | 1902 | if (fldtype != TREE_TYPE (field)) |
4b978f96 | 1903 | next = cp_convert_and_check (TREE_TYPE (field), next, complain); |
08c35030 | 1904 | picflags |= picflag_from_initializer (next); |
eb03e424 JJ |
1905 | /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR. */ |
1906 | if (TREE_CODE (next) == CONSTRUCTOR | |
1907 | && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next)) | |
1908 | { | |
1909 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
1910 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0; | |
1911 | } | |
4038c495 | 1912 | CONSTRUCTOR_APPEND_ELT (v, field, next); |
8d08fdba | 1913 | } |
8d08fdba | 1914 | |
aaa1b10f | 1915 | if (idx < CONSTRUCTOR_NELTS (init)) |
754af126 PC |
1916 | { |
1917 | if (complain & tf_error) | |
d68ddd2b JJ |
1918 | { |
1919 | constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx]; | |
1920 | /* For better diagnostics, try to find out if it is really | |
1921 | the case of too many initializers or if designators are | |
1922 | in incorrect order. */ | |
1923 | if (designator_skip == 1 && ce->index) | |
1924 | { | |
1925 | gcc_assert (TREE_CODE (ce->index) == FIELD_DECL | |
1926 | || identifier_p (ce->index)); | |
1927 | for (field = TYPE_FIELDS (type); | |
1928 | field; field = DECL_CHAIN (field)) | |
1929 | { | |
d68ddd2b JJ |
1930 | if (TREE_CODE (field) != FIELD_DECL |
1931 | || (DECL_ARTIFICIAL (field) | |
1932 | && !(cxx_dialect >= cxx17 | |
1933 | && DECL_FIELD_IS_BASE (field)))) | |
1934 | continue; | |
1935 | ||
7c30b12a PC |
1936 | if (DECL_UNNAMED_BIT_FIELD (field)) |
1937 | continue; | |
1938 | ||
d68ddd2b JJ |
1939 | if (ce->index == field || ce->index == DECL_NAME (field)) |
1940 | break; | |
d68ddd2b JJ |
1941 | } |
1942 | } | |
1943 | if (field) | |
1944 | error ("designator order for field %qD does not match declaration " | |
1945 | "order in %qT", field, type); | |
1946 | else | |
1947 | error ("too many initializers for %qT", type); | |
1948 | } | |
754af126 PC |
1949 | else |
1950 | return PICFLAG_ERRONEOUS; | |
1951 | } | |
1952 | ||
4038c495 | 1953 | CONSTRUCTOR_ELTS (init) = v; |
08c35030 | 1954 | return picflags; |
4038c495 | 1955 | } |
8d08fdba | 1956 | |
4038c495 | 1957 | /* Subroutine of process_init_constructor, which will process a single |
13a44ee0 | 1958 | initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*) |
4038c495 | 1959 | which describe the initializer. */ |
8d08fdba | 1960 | |
4038c495 | 1961 | static int |
08c35030 | 1962 | process_init_constructor_union (tree type, tree init, int nested, int flags, |
754af126 | 1963 | tsubst_flags_t complain) |
4038c495 GB |
1964 | { |
1965 | constructor_elt *ce; | |
fc94bfc5 | 1966 | int len; |
8d08fdba | 1967 | |
426b9428 PP |
1968 | /* If the initializer was empty, use the union's NSDMI if it has one. |
1969 | Otherwise use default zero initialization. */ | |
9771b263 | 1970 | if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))) |
426b9428 PP |
1971 | { |
1972 | for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) | |
1973 | { | |
bb7d75ff PP |
1974 | if (TREE_CODE (field) == FIELD_DECL |
1975 | && DECL_INITIAL (field) != NULL_TREE) | |
426b9428 | 1976 | { |
570f86f9 JJ |
1977 | tree val = get_nsdmi (field, /*in_ctor=*/false, complain); |
1978 | if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) | |
1979 | && find_placeholders (val)) | |
1980 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
1981 | CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init), field, val); | |
426b9428 PP |
1982 | break; |
1983 | } | |
1984 | } | |
1985 | ||
1986 | if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))) | |
1987 | return 0; | |
1988 | } | |
4038c495 | 1989 | |
9771b263 | 1990 | len = CONSTRUCTOR_ELTS (init)->length (); |
fc94bfc5 JM |
1991 | if (len > 1) |
1992 | { | |
754af126 PC |
1993 | if (!(complain & tf_error)) |
1994 | return PICFLAG_ERRONEOUS; | |
fc94bfc5 | 1995 | error ("too many initializers for %qT", type); |
9771b263 | 1996 | CONSTRUCTOR_ELTS (init)->block_remove (1, len-1); |
fc94bfc5 JM |
1997 | } |
1998 | ||
9771b263 | 1999 | ce = &(*CONSTRUCTOR_ELTS (init))[0]; |
4038c495 GB |
2000 | |
2001 | /* If this element specifies a field, initialize via that field. */ | |
2002 | if (ce->index) | |
2003 | { | |
2004 | if (TREE_CODE (ce->index) == FIELD_DECL) | |
2005 | ; | |
9dc6f476 | 2006 | else if (identifier_p (ce->index)) |
4038c495 GB |
2007 | { |
2008 | /* This can happen within a cast, see g++.dg/opt/cse2.C. */ | |
2009 | tree name = ce->index; | |
2010 | tree field; | |
2011 | for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) | |
2012 | if (DECL_NAME (field) == name) | |
2013 | break; | |
2014 | if (!field) | |
8d08fdba | 2015 | { |
754af126 PC |
2016 | if (complain & tf_error) |
2017 | error ("no field %qD found in union being initialized", | |
2018 | field); | |
4038c495 | 2019 | ce->value = error_mark_node; |
8d08fdba | 2020 | } |
4038c495 GB |
2021 | ce->index = field; |
2022 | } | |
2023 | else | |
2024 | { | |
2025 | gcc_assert (TREE_CODE (ce->index) == INTEGER_CST | |
2026 | || TREE_CODE (ce->index) == RANGE_EXPR); | |
754af126 PC |
2027 | if (complain & tf_error) |
2028 | error ("index value instead of field name in union initializer"); | |
4038c495 | 2029 | ce->value = error_mark_node; |
8d08fdba | 2030 | } |
8d08fdba | 2031 | } |
4038c495 | 2032 | else |
8d08fdba | 2033 | { |
8d08fdba MS |
2034 | /* Find the first named field. ANSI decided in September 1990 |
2035 | that only named fields count here. */ | |
4038c495 | 2036 | tree field = TYPE_FIELDS (type); |
17bbb839 | 2037 | while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL)) |
8d08fdba | 2038 | field = TREE_CHAIN (field); |
9bfea41b JM |
2039 | if (field == NULL_TREE) |
2040 | { | |
754af126 PC |
2041 | if (complain & tf_error) |
2042 | error ("too many initializers for %qT", type); | |
9bfea41b JM |
2043 | ce->value = error_mark_node; |
2044 | } | |
4038c495 GB |
2045 | ce->index = field; |
2046 | } | |
8d08fdba | 2047 | |
4038c495 | 2048 | if (ce->value && ce->value != error_mark_node) |
a8c55cac | 2049 | ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested, |
08c35030 | 2050 | flags, complain); |
8d08fdba | 2051 | |
eb03e424 JJ |
2052 | /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR. */ |
2053 | if (ce->value | |
2054 | && TREE_CODE (ce->value) == CONSTRUCTOR | |
2055 | && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value)) | |
2056 | { | |
2057 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1; | |
2058 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0; | |
2059 | } | |
4038c495 GB |
2060 | return picflag_from_initializer (ce->value); |
2061 | } | |
8d08fdba | 2062 | |
4038c495 GB |
2063 | /* Process INIT, a constructor for a variable of aggregate type TYPE. The |
2064 | constructor is a brace-enclosed initializer, and will be modified in-place. | |
2065 | ||
2066 | Each element is converted to the right type through digest_init, and | |
2067 | missing initializers are added following the language rules (zero-padding, | |
2068 | etc.). | |
8d08fdba | 2069 | |
4038c495 GB |
2070 | After the execution, the initializer will have TREE_CONSTANT if all elts are |
2071 | constant, and TREE_STATIC set if, in addition, all elts are simple enough | |
2072 | constants that the assembler and linker can compute them. | |
3db45ab5 | 2073 | |
4038c495 GB |
2074 | The function returns the initializer itself, or error_mark_node in case |
2075 | of error. */ | |
2076 | ||
2077 | static tree | |
08c35030 | 2078 | process_init_constructor (tree type, tree init, int nested, int flags, |
a8c55cac | 2079 | tsubst_flags_t complain) |
4038c495 | 2080 | { |
08c35030 | 2081 | int picflags; |
4038c495 GB |
2082 | |
2083 | gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); | |
2084 | ||
b55b02ea | 2085 | if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type)) |
08c35030 BE |
2086 | picflags = process_init_constructor_array (type, init, nested, flags, |
2087 | complain); | |
4038c495 | 2088 | else if (TREE_CODE (type) == RECORD_TYPE) |
08c35030 BE |
2089 | picflags = process_init_constructor_record (type, init, nested, flags, |
2090 | complain); | |
4038c495 | 2091 | else if (TREE_CODE (type) == UNION_TYPE) |
08c35030 BE |
2092 | picflags = process_init_constructor_union (type, init, nested, flags, |
2093 | complain); | |
4038c495 GB |
2094 | else |
2095 | gcc_unreachable (); | |
8d08fdba | 2096 | |
08c35030 | 2097 | if (picflags & PICFLAG_ERRONEOUS) |
8d08fdba MS |
2098 | return error_mark_node; |
2099 | ||
4038c495 | 2100 | TREE_TYPE (init) = type; |
8c081e84 | 2101 | if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) |
4038c495 | 2102 | cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0); |
08c35030 | 2103 | if (picflags & PICFLAG_SIDE_EFFECTS) |
dd5593fc JM |
2104 | { |
2105 | TREE_CONSTANT (init) = false; | |
2106 | TREE_SIDE_EFFECTS (init) = true; | |
2107 | } | |
08c35030 | 2108 | else if (picflags & PICFLAG_NOT_ALL_CONSTANT) |
c151a342 JM |
2109 | { |
2110 | /* Make sure TREE_CONSTANT isn't set from build_constructor. */ | |
2111 | TREE_CONSTANT (init) = false; | |
2112 | TREE_SIDE_EFFECTS (init) = false; | |
2113 | } | |
743af85b | 2114 | else |
6de9cd9a | 2115 | { |
4038c495 | 2116 | TREE_CONSTANT (init) = 1; |
c151a342 | 2117 | TREE_SIDE_EFFECTS (init) = false; |
08c35030 | 2118 | if (!(picflags & PICFLAG_NOT_ALL_SIMPLE)) |
4038c495 | 2119 | TREE_STATIC (init) = 1; |
6de9cd9a | 2120 | } |
e948436e JM |
2121 | if (picflags & PICFLAG_VEC_INIT) |
2122 | { | |
2123 | /* Defer default-initialization of array elements with no corresponding | |
2124 | initializer-clause until later so we can use a loop. */ | |
2125 | TREE_TYPE (init) = init_list_type_node; | |
2126 | init = build_vec_init_expr (type, init, complain); | |
119cea98 | 2127 | init = get_target_expr (init); |
e948436e | 2128 | } |
4038c495 | 2129 | return init; |
8d08fdba MS |
2130 | } |
2131 | \f | |
2132 | /* Given a structure or union value DATUM, construct and return | |
2133 | the structure or union component which results from narrowing | |
a29e1034 | 2134 | that value to the base specified in BASETYPE. For example, given the |
8d08fdba MS |
2135 | hierarchy |
2136 | ||
2137 | class L { int ii; }; | |
2138 | class A : L { ... }; | |
2139 | class B : L { ... }; | |
2140 | class C : A, B { ... }; | |
2141 | ||
2142 | and the declaration | |
2143 | ||
2144 | C x; | |
2145 | ||
2146 | then the expression | |
2147 | ||
be99da77 | 2148 | x.A::ii refers to the ii member of the L part of |
38e01259 | 2149 | the A part of the C object named by X. In this case, |
aa52c1ff JM |
2150 | DATUM would be x, and BASETYPE would be A. |
2151 | ||
477f6664 JM |
2152 | I used to think that this was nonconformant, that the standard specified |
2153 | that first we look up ii in A, then convert x to an L& and pull out the | |
2154 | ii part. But in fact, it does say that we convert x to an A&; A here | |
a29e1034 JM |
2155 | is known as the "naming class". (jason 2000-12-19) |
2156 | ||
2157 | BINFO_P points to a variable initialized either to NULL_TREE or to the | |
2158 | binfo for the specific base subobject we want to convert to. */ | |
8d08fdba MS |
2159 | |
2160 | tree | |
0a8cb79e | 2161 | build_scoped_ref (tree datum, tree basetype, tree* binfo_p) |
8d08fdba | 2162 | { |
338d90b8 | 2163 | tree binfo; |
8d08fdba MS |
2164 | |
2165 | if (datum == error_mark_node) | |
2166 | return error_mark_node; | |
a29e1034 JM |
2167 | if (*binfo_p) |
2168 | binfo = *binfo_p; | |
2169 | else | |
22854930 PC |
2170 | binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, |
2171 | NULL, tf_warning_or_error); | |
8d08fdba | 2172 | |
a29e1034 JM |
2173 | if (!binfo || binfo == error_mark_node) |
2174 | { | |
2175 | *binfo_p = NULL_TREE; | |
2176 | if (!binfo) | |
2177 | error_not_base_type (basetype, TREE_TYPE (datum)); | |
2178 | return error_mark_node; | |
2179 | } | |
8d08fdba | 2180 | |
a29e1034 | 2181 | *binfo_p = binfo; |
a271590a PC |
2182 | return build_base_path (PLUS_EXPR, datum, binfo, 1, |
2183 | tf_warning_or_error); | |
8d08fdba MS |
2184 | } |
2185 | ||
2186 | /* Build a reference to an object specified by the C++ `->' operator. | |
2187 | Usually this just involves dereferencing the object, but if the | |
2188 | `->' operator is overloaded, then such overloads must be | |
2189 | performed until an object which does not have the `->' operator | |
2190 | overloaded is found. An error is reported when circular pointer | |
2191 | delegation is detected. */ | |
e92cc029 | 2192 | |
8d08fdba | 2193 | tree |
4fe977f2 | 2194 | build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain) |
8d08fdba | 2195 | { |
d17811fd | 2196 | tree orig_expr = expr; |
d17811fd | 2197 | tree type = TREE_TYPE (expr); |
a703fb38 | 2198 | tree last_rval = NULL_TREE; |
9771b263 | 2199 | vec<tree, va_gc> *types_memoized = NULL; |
8d08fdba MS |
2200 | |
2201 | if (type == error_mark_node) | |
2202 | return error_mark_node; | |
2203 | ||
5156628f | 2204 | if (processing_template_decl) |
d17811fd | 2205 | { |
771fd4ae JM |
2206 | tree ttype = NULL_TREE; |
2207 | if (type && TYPE_PTR_P (type)) | |
2208 | ttype = TREE_TYPE (type); | |
2209 | if (ttype && !dependent_scope_p (ttype)) | |
23cb7266 JM |
2210 | /* Pointer to current instantiation, don't treat as dependent. */; |
2211 | else if (type_dependent_expression_p (expr)) | |
771fd4ae JM |
2212 | { |
2213 | expr = build_min_nt_loc (loc, ARROW_EXPR, expr); | |
2214 | TREE_TYPE (expr) = ttype; | |
2215 | return expr; | |
2216 | } | |
d17811fd | 2217 | } |
5566b478 | 2218 | |
9e1e64ec | 2219 | if (MAYBE_CLASS_TYPE_P (type)) |
8d08fdba | 2220 | { |
6904f4b4 DK |
2221 | struct tinst_level *actual_inst = current_instantiation (); |
2222 | tree fn = NULL; | |
2223 | ||
4fe977f2 PC |
2224 | while ((expr = build_new_op (loc, COMPONENT_REF, |
2225 | LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE, | |
bb2a7f80 | 2226 | NULL_TREE, &fn, complain))) |
8d08fdba | 2227 | { |
d17811fd | 2228 | if (expr == error_mark_node) |
8d08fdba MS |
2229 | return error_mark_node; |
2230 | ||
75a0d320 PC |
2231 | /* This provides a better instantiation backtrace in case of |
2232 | error. */ | |
6904f4b4 | 2233 | if (fn && DECL_USE_TEMPLATE (fn)) |
75a0d320 PC |
2234 | push_tinst_level_loc (fn, |
2235 | (current_instantiation () != actual_inst) | |
2236 | ? DECL_SOURCE_LOCATION (fn) | |
2237 | : input_location); | |
6904f4b4 DK |
2238 | fn = NULL; |
2239 | ||
bfdb7b70 NF |
2240 | if (vec_member (TREE_TYPE (expr), types_memoized)) |
2241 | { | |
ff2f581b PC |
2242 | if (complain & tf_error) |
2243 | error ("circular pointer delegation detected"); | |
bfdb7b70 NF |
2244 | return error_mark_node; |
2245 | } | |
f038ec69 | 2246 | |
9771b263 | 2247 | vec_safe_push (types_memoized, TREE_TYPE (expr)); |
d17811fd | 2248 | last_rval = expr; |
c8094d83 | 2249 | } |
297dcfb3 | 2250 | |
6904f4b4 DK |
2251 | while (current_instantiation () != actual_inst) |
2252 | pop_tinst_level (); | |
2253 | ||
297dcfb3 MM |
2254 | if (last_rval == NULL_TREE) |
2255 | { | |
ff2f581b PC |
2256 | if (complain & tf_error) |
2257 | error ("base operand of %<->%> has non-pointer type %qT", type); | |
297dcfb3 MM |
2258 | return error_mark_node; |
2259 | } | |
2260 | ||
9f613f06 | 2261 | if (TYPE_REF_P (TREE_TYPE (last_rval))) |
8d08fdba MS |
2262 | last_rval = convert_from_reference (last_rval); |
2263 | } | |
2264 | else | |
df265344 PC |
2265 | { |
2266 | last_rval = decay_conversion (expr, complain); | |
2267 | if (last_rval == error_mark_node) | |
2268 | return error_mark_node; | |
2269 | } | |
8d08fdba | 2270 | |
50e10fa8 | 2271 | if (TYPE_PTR_P (TREE_TYPE (last_rval))) |
d17811fd MM |
2272 | { |
2273 | if (processing_template_decl) | |
8e1daa34 | 2274 | { |
7448d2e7 JM |
2275 | expr = build_min (ARROW_EXPR, TREE_TYPE (TREE_TYPE (last_rval)), |
2276 | orig_expr); | |
2277 | TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (last_rval); | |
8e1daa34 NS |
2278 | return expr; |
2279 | } | |
d17811fd | 2280 | |
3554d8ff | 2281 | return cp_build_indirect_ref (loc, last_rval, RO_ARROW, complain); |
d17811fd | 2282 | } |
8d08fdba | 2283 | |
ff2f581b PC |
2284 | if (complain & tf_error) |
2285 | { | |
2286 | if (types_memoized) | |
2287 | error ("result of %<operator->()%> yields non-pointer result"); | |
2288 | else | |
2289 | error ("base operand of %<->%> is not a pointer"); | |
2290 | } | |
8d08fdba MS |
2291 | return error_mark_node; |
2292 | } | |
2293 | ||
d6b4ea85 MM |
2294 | /* Return an expression for "DATUM .* COMPONENT". DATUM has not |
2295 | already been checked out to be of aggregate type. */ | |
e92cc029 | 2296 | |
8d08fdba | 2297 | tree |
89fcabaf | 2298 | build_m_component_ref (tree datum, tree component, tsubst_flags_t complain) |
8d08fdba | 2299 | { |
d6b4ea85 | 2300 | tree ptrmem_type; |
c3e899c1 | 2301 | tree objtype; |
d6b4ea85 | 2302 | tree type; |
71851aaa | 2303 | tree binfo; |
cad7e87b | 2304 | tree ctype; |
8d08fdba | 2305 | |
416f380b JJ |
2306 | datum = mark_lvalue_use (datum); |
2307 | component = mark_rvalue_use (component); | |
87867ff6 | 2308 | |
fea3397e MP |
2309 | if (error_operand_p (datum) || error_operand_p (component)) |
2310 | return error_mark_node; | |
2311 | ||
d6b4ea85 | 2312 | ptrmem_type = TREE_TYPE (component); |
66b1156a | 2313 | if (!TYPE_PTRMEM_P (ptrmem_type)) |
8d08fdba | 2314 | { |
89fcabaf PC |
2315 | if (complain & tf_error) |
2316 | error ("%qE cannot be used as a member pointer, since it is of " | |
2317 | "type %qT", component, ptrmem_type); | |
8d08fdba MS |
2318 | return error_mark_node; |
2319 | } | |
c8094d83 MS |
2320 | |
2321 | objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum)); | |
9e1e64ec | 2322 | if (! MAYBE_CLASS_TYPE_P (objtype)) |
51c184be | 2323 | { |
89fcabaf PC |
2324 | if (complain & tf_error) |
2325 | error ("cannot apply member pointer %qE to %qE, which is of " | |
2326 | "non-class type %qT", component, datum, objtype); | |
51c184be MS |
2327 | return error_mark_node; |
2328 | } | |
71851aaa | 2329 | |
d6b4ea85 | 2330 | type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type); |
cad7e87b NS |
2331 | ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type)); |
2332 | ||
2333 | if (!COMPLETE_TYPE_P (ctype)) | |
8d08fdba | 2334 | { |
cad7e87b NS |
2335 | if (!same_type_p (ctype, objtype)) |
2336 | goto mismatch; | |
2337 | binfo = NULL; | |
2338 | } | |
2339 | else | |
2340 | { | |
22854930 | 2341 | binfo = lookup_base (objtype, ctype, ba_check, NULL, complain); |
c8094d83 | 2342 | |
cad7e87b NS |
2343 | if (!binfo) |
2344 | { | |
2345 | mismatch: | |
89fcabaf PC |
2346 | if (complain & tf_error) |
2347 | error ("pointer to member type %qT incompatible with object " | |
2348 | "type %qT", type, objtype); | |
cad7e87b NS |
2349 | return error_mark_node; |
2350 | } | |
2351 | else if (binfo == error_mark_node) | |
2352 | return error_mark_node; | |
8d08fdba MS |
2353 | } |
2354 | ||
66b1156a | 2355 | if (TYPE_PTRDATAMEM_P (ptrmem_type)) |
d6b4ea85 | 2356 | { |
955da5e5 | 2357 | bool is_lval = real_lvalue_p (datum); |
b5119fa1 RG |
2358 | tree ptype; |
2359 | ||
d6b4ea85 MM |
2360 | /* Compute the type of the field, as described in [expr.ref]. |
2361 | There's no such thing as a mutable pointer-to-member, so | |
2362 | things are not as complex as they are for references to | |
2363 | non-static data members. */ | |
2364 | type = cp_build_qualified_type (type, | |
c8094d83 | 2365 | (cp_type_quals (type) |
d6b4ea85 | 2366 | | cp_type_quals (TREE_TYPE (datum)))); |
cad7e87b NS |
2367 | |
2368 | datum = build_address (datum); | |
c8094d83 | 2369 | |
cad7e87b NS |
2370 | /* Convert object to the correct base. */ |
2371 | if (binfo) | |
89fcabaf PC |
2372 | { |
2373 | datum = build_base_path (PLUS_EXPR, datum, binfo, 1, complain); | |
2374 | if (datum == error_mark_node) | |
2375 | return error_mark_node; | |
2376 | } | |
c8094d83 | 2377 | |
a5ac359a MM |
2378 | /* Build an expression for "object + offset" where offset is the |
2379 | value stored in the pointer-to-data-member. */ | |
b5119fa1 | 2380 | ptype = build_pointer_type (type); |
d3f48f68 PP |
2381 | datum = cp_convert (ptype, datum, complain); |
2382 | if (!processing_template_decl) | |
2383 | datum = build2 (POINTER_PLUS_EXPR, ptype, | |
2384 | datum, convert_to_ptrofftype (component)); | |
2385 | datum = cp_fully_fold (datum); | |
04757a2a | 2386 | datum = cp_build_fold_indirect_ref (datum); |
89fcabaf PC |
2387 | if (datum == error_mark_node) |
2388 | return error_mark_node; | |
2389 | ||
0171567e | 2390 | /* If the object expression was an rvalue, return an rvalue. */ |
955da5e5 | 2391 | if (!is_lval) |
0171567e JM |
2392 | datum = move (datum); |
2393 | return datum; | |
d6b4ea85 MM |
2394 | } |
2395 | else | |
2eed8e37 BK |
2396 | { |
2397 | /* 5.5/6: In a .* expression whose object expression is an rvalue, the | |
2398 | program is ill-formed if the second operand is a pointer to member | |
b04445d4 | 2399 | function with ref-qualifier & (for C++20: unless its cv-qualifier-seq |
681f18d1 JJ |
2400 | is const). In a .* expression whose object expression is an lvalue, |
2401 | the program is ill-formed if the second operand is a pointer to member | |
2402 | function with ref-qualifier &&. */ | |
2eed8e37 BK |
2403 | if (FUNCTION_REF_QUALIFIED (type)) |
2404 | { | |
72b3e203 | 2405 | bool lval = lvalue_p (datum); |
2eed8e37 | 2406 | if (lval && FUNCTION_RVALUE_QUALIFIED (type)) |
7c55f410 PC |
2407 | { |
2408 | if (complain & tf_error) | |
2409 | error ("pointer-to-member-function type %qT requires an rvalue", | |
2410 | ptrmem_type); | |
2411 | return error_mark_node; | |
2412 | } | |
96d155c6 | 2413 | else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type)) |
7c55f410 | 2414 | { |
96d155c6 JM |
2415 | if ((type_memfn_quals (type) |
2416 | & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) | |
2417 | != TYPE_QUAL_CONST) | |
2418 | { | |
2419 | if (complain & tf_error) | |
2420 | error ("pointer-to-member-function type %qT requires " | |
2421 | "an lvalue", ptrmem_type); | |
2422 | return error_mark_node; | |
2423 | } | |
b04445d4 | 2424 | else if (cxx_dialect < cxx20) |
96d155c6 JM |
2425 | { |
2426 | if (complain & tf_warning_or_error) | |
2427 | pedwarn (input_location, OPT_Wpedantic, | |
2428 | "pointer-to-member-function type %qT requires " | |
b04445d4 | 2429 | "an lvalue before C++20", ptrmem_type); |
96d155c6 JM |
2430 | else |
2431 | return error_mark_node; | |
2432 | } | |
7c55f410 | 2433 | } |
2eed8e37 BK |
2434 | } |
2435 | return build2 (OFFSET_REF, type, datum, component); | |
2436 | } | |
8d08fdba MS |
2437 | } |
2438 | ||
fc378698 | 2439 | /* Return a tree node for the expression TYPENAME '(' PARMS ')'. */ |
e92cc029 | 2440 | |
ca6932ad PC |
2441 | static tree |
2442 | build_functional_cast_1 (location_t loc, tree exp, tree parms, | |
2443 | tsubst_flags_t complain) | |
8d08fdba MS |
2444 | { |
2445 | /* This is either a call to a constructor, | |
2446 | or a C cast in C++'s `functional' notation. */ | |
0fcedd9c JM |
2447 | |
2448 | /* The type to which we are casting. */ | |
fc378698 | 2449 | tree type; |
8d08fdba | 2450 | |
76b67a0a | 2451 | if (error_operand_p (exp) || parms == error_mark_node) |
8d08fdba MS |
2452 | return error_mark_node; |
2453 | ||
4b0d3cbe | 2454 | if (TREE_CODE (exp) == TYPE_DECL) |
0fbf4384 PC |
2455 | { |
2456 | type = TREE_TYPE (exp); | |
2457 | ||
b46b715d | 2458 | if (DECL_ARTIFICIAL (exp)) |
8433baad | 2459 | cp_handle_deprecated_or_unavailable (type); |
0fbf4384 | 2460 | } |
8d08fdba MS |
2461 | else |
2462 | type = exp; | |
2463 | ||
4ddd8a74 JM |
2464 | /* We need to check this explicitly, since value-initialization of |
2465 | arrays is allowed in other situations. */ | |
2466 | if (TREE_CODE (type) == ARRAY_TYPE) | |
2467 | { | |
2468 | if (complain & tf_error) | |
ad774d0d | 2469 | error_at (loc, "functional cast to array type %qT", type); |
4ddd8a74 JM |
2470 | return error_mark_node; |
2471 | } | |
2472 | ||
76b294d4 | 2473 | if (tree anode = type_uses_auto (type)) |
efaa76b3 | 2474 | { |
93810fd6 MP |
2475 | tree init; |
2476 | if (CLASS_PLACEHOLDER_TEMPLATE (anode)) | |
2477 | init = parms; | |
2478 | /* C++23 auto(x). */ | |
2479 | else if (!AUTO_IS_DECLTYPE (anode) | |
2480 | && list_length (parms) == 1) | |
76b294d4 | 2481 | { |
93810fd6 | 2482 | init = TREE_VALUE (parms); |
97f76b5f MP |
2483 | if (is_constrained_auto (anode)) |
2484 | { | |
2485 | if (complain & tf_error) | |
2486 | error_at (loc, "%<auto(x)%> cannot be constrained"); | |
2487 | return error_mark_node; | |
2488 | } | |
2489 | else if (cxx_dialect < cxx23) | |
93810fd6 MP |
2490 | pedwarn (loc, OPT_Wc__23_extensions, |
2491 | "%<auto(x)%> only available with " | |
2492 | "%<-std=c++2b%> or %<-std=gnu++2b%>"); | |
76b294d4 | 2493 | } |
8913b2c2 | 2494 | else |
76b294d4 | 2495 | { |
93810fd6 MP |
2496 | if (complain & tf_error) |
2497 | error_at (loc, "invalid use of %qT", anode); | |
2498 | return error_mark_node; | |
76b294d4 | 2499 | } |
93810fd6 MP |
2500 | type = do_auto_deduction (type, init, anode, complain, |
2501 | adc_variable_type); | |
2502 | if (type == error_mark_node) | |
2503 | return error_mark_node; | |
efaa76b3 PC |
2504 | } |
2505 | ||
5156628f | 2506 | if (processing_template_decl) |
8e1daa34 | 2507 | { |
351ccf20 JM |
2508 | tree t; |
2509 | ||
2510 | /* Diagnose this even in a template. We could also try harder | |
2511 | to give all the usual errors when the type and args are | |
2512 | non-dependent... */ | |
9f613f06 | 2513 | if (TYPE_REF_P (type) && !parms) |
351ccf20 JM |
2514 | { |
2515 | if (complain & tf_error) | |
ad774d0d | 2516 | error_at (loc, "invalid value-initialization of reference type"); |
351ccf20 JM |
2517 | return error_mark_node; |
2518 | } | |
2519 | ||
2520 | t = build_min (CAST_EXPR, type, parms); | |
8e1daa34 NS |
2521 | /* We don't know if it will or will not have side effects. */ |
2522 | TREE_SIDE_EFFECTS (t) = 1; | |
2523 | return t; | |
2524 | } | |
5566b478 | 2525 | |
9e1e64ec | 2526 | if (! MAYBE_CLASS_TYPE_P (type)) |
8d08fdba | 2527 | { |
8d08fdba | 2528 | if (parms == NULL_TREE) |
e5dda971 JM |
2529 | { |
2530 | if (VOID_TYPE_P (type)) | |
632f2871 | 2531 | return void_node; |
908e152c | 2532 | return build_value_init (cv_unqualified (type), complain); |
e5dda971 | 2533 | } |
8ccc31eb | 2534 | |
f0b99d6c | 2535 | /* This must build a C cast. */ |
d555b1c7 | 2536 | parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain); |
ca6932ad | 2537 | return cp_build_c_cast (loc, type, parms, complain); |
8d08fdba MS |
2538 | } |
2539 | ||
45537677 MS |
2540 | /* Prepare to evaluate as a call to a constructor. If this expression |
2541 | is actually used, for example, | |
c8094d83 | 2542 | |
45537677 | 2543 | return X (arg1, arg2, ...); |
c8094d83 | 2544 | |
45537677 MS |
2545 | then the slot being initialized will be filled in. */ |
2546 | ||
309714d4 | 2547 | if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)) |
d0f062fb | 2548 | return error_mark_node; |
c17fa0f2 | 2549 | if (abstract_virtuals_error (ACU_CAST, type, complain)) |
a7a64a77 | 2550 | return error_mark_node; |
8d08fdba | 2551 | |
0fcedd9c JM |
2552 | /* [expr.type.conv] |
2553 | ||
2554 | If the expression list is a single-expression, the type | |
2555 | conversion is equivalent (in definedness, and if defined in | |
2556 | meaning) to the corresponding cast expression. */ | |
8d08fdba | 2557 | if (parms && TREE_CHAIN (parms) == NULL_TREE) |
ca6932ad | 2558 | return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain); |
8d08fdba | 2559 | |
0fcedd9c JM |
2560 | /* [expr.type.conv] |
2561 | ||
2562 | The expression T(), where T is a simple-type-specifier for a | |
2563 | non-array complete object type or the (possibly cv-qualified) | |
2564 | void type, creates an rvalue of the specified type, which is | |
2565 | value-initialized. */ | |
2566 | ||
30d1352e | 2567 | if (parms == NULL_TREE) |
3551c177 | 2568 | { |
309714d4 | 2569 | exp = build_value_init (type, complain); |
c17fa0f2 | 2570 | exp = get_target_expr (exp, complain); |
fa2200cb | 2571 | return exp; |
3551c177 JM |
2572 | } |
2573 | ||
0fcedd9c | 2574 | /* Call the constructor. */ |
cd9cf97b | 2575 | releasing_vec parmvec; |
c166b898 | 2576 | for (; parms != NULL_TREE; parms = TREE_CHAIN (parms)) |
9771b263 | 2577 | vec_safe_push (parmvec, TREE_VALUE (parms)); |
c166b898 ILT |
2578 | exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, |
2579 | &parmvec, type, LOOKUP_NORMAL, complain); | |
8d08fdba | 2580 | |
fc378698 | 2581 | if (exp == error_mark_node) |
a0a33927 | 2582 | return error_mark_node; |
8d08fdba | 2583 | |
362115a9 | 2584 | return build_cplus_new (type, exp, complain); |
8d08fdba | 2585 | } |
ca6932ad PC |
2586 | |
2587 | tree | |
2588 | build_functional_cast (location_t loc, tree exp, tree parms, | |
2589 | tsubst_flags_t complain) | |
2590 | { | |
2591 | tree result = build_functional_cast_1 (loc, exp, parms, complain); | |
2592 | protected_set_expr_location (result, loc); | |
2593 | return result; | |
2594 | } | |
8d08fdba | 2595 | \f |
46b02c6d | 2596 | |
4cc1d462 NS |
2597 | /* Add new exception specifier SPEC, to the LIST we currently have. |
2598 | If it's already in LIST then do nothing. | |
2599 | Moan if it's bad and we're allowed to. COMPLAIN < 0 means we | |
2600 | know what we're doing. */ | |
2601 | ||
2602 | tree | |
779d8a5a | 2603 | add_exception_specifier (tree list, tree spec, tsubst_flags_t complain) |
4cc1d462 | 2604 | { |
ef09717a | 2605 | bool ok; |
4cc1d462 | 2606 | tree core = spec; |
ef09717a | 2607 | bool is_ptr; |
71205d17 | 2608 | diagnostic_t diag_type = DK_UNSPECIFIED; /* none */ |
c8094d83 | 2609 | |
4cc1d462 NS |
2610 | if (spec == error_mark_node) |
2611 | return list; | |
c8094d83 | 2612 | |
50bc768d | 2613 | gcc_assert (spec && (!list || TREE_VALUE (list))); |
c8094d83 | 2614 | |
4cc1d462 NS |
2615 | /* [except.spec] 1, type in an exception specifier shall not be |
2616 | incomplete, or pointer or ref to incomplete other than pointer | |
2617 | to cv void. */ | |
50e10fa8 | 2618 | is_ptr = TYPE_PTR_P (core); |
9f613f06 | 2619 | if (is_ptr || TYPE_REF_P (core)) |
4cc1d462 NS |
2620 | core = TREE_TYPE (core); |
2621 | if (complain < 0) | |
ef09717a | 2622 | ok = true; |
b72801e2 | 2623 | else if (VOID_TYPE_P (core)) |
4cc1d462 NS |
2624 | ok = is_ptr; |
2625 | else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM) | |
ef09717a | 2626 | ok = true; |
baeb4732 | 2627 | else if (processing_template_decl) |
ef09717a | 2628 | ok = true; |
02a32ab4 RS |
2629 | else if (!verify_type_context (input_location, TCTX_EXCEPTIONS, core, |
2630 | !(complain & tf_error))) | |
2631 | return error_mark_node; | |
4cc1d462 | 2632 | else |
5aa3396c | 2633 | { |
ef09717a | 2634 | ok = true; |
5aa3396c | 2635 | /* 15.4/1 says that types in an exception specifier must be complete, |
0cbd7506 MS |
2636 | but it seems more reasonable to only require this on definitions |
2637 | and calls. So just give a pedwarn at this point; we will give an | |
2638 | error later if we hit one of those two cases. */ | |
5aa3396c | 2639 | if (!COMPLETE_TYPE_P (complete_type (core))) |
71205d17 | 2640 | diag_type = DK_PEDWARN; /* pedwarn */ |
5aa3396c | 2641 | } |
baeb4732 | 2642 | |
4cc1d462 NS |
2643 | if (ok) |
2644 | { | |
2645 | tree probe; | |
c8094d83 | 2646 | |
4cc1d462 | 2647 | for (probe = list; probe; probe = TREE_CHAIN (probe)) |
0cbd7506 MS |
2648 | if (same_type_p (TREE_VALUE (probe), spec)) |
2649 | break; | |
4cc1d462 | 2650 | if (!probe) |
80b1331c | 2651 | list = tree_cons (NULL_TREE, spec, list); |
4cc1d462 | 2652 | } |
5aa3396c | 2653 | else |
71205d17 | 2654 | diag_type = DK_ERROR; /* error */ |
c8094d83 | 2655 | |
852497a3 JM |
2656 | if (diag_type != DK_UNSPECIFIED |
2657 | && (complain & tf_warning_or_error)) | |
5aa3396c JM |
2658 | cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type); |
2659 | ||
4cc1d462 NS |
2660 | return list; |
2661 | } | |
03378143 | 2662 | |
b273cdb1 JM |
2663 | /* Like nothrow_spec_p, but don't abort on deferred noexcept. */ |
2664 | ||
2665 | static bool | |
2666 | nothrow_spec_p_uninst (const_tree spec) | |
2667 | { | |
2668 | if (DEFERRED_NOEXCEPT_SPEC_P (spec)) | |
2669 | return false; | |
2670 | return nothrow_spec_p (spec); | |
2671 | } | |
2672 | ||
03378143 | 2673 | /* Combine the two exceptions specifier lists LIST and ADD, and return |
b15ea309 | 2674 | their union. */ |
03378143 NS |
2675 | |
2676 | tree | |
b15ea309 | 2677 | merge_exception_specifiers (tree list, tree add) |
03378143 | 2678 | { |
b273cdb1 JM |
2679 | tree noex, orig_list; |
2680 | ||
9d35a27a JM |
2681 | if (list == error_mark_node || add == error_mark_node) |
2682 | return error_mark_node; | |
2683 | ||
5e3f417f JM |
2684 | /* No exception-specifier or noexcept(false) are less strict than |
2685 | anything else. Prefer the newer variant (LIST). */ | |
2686 | if (!list || list == noexcept_false_spec) | |
2687 | return list; | |
2688 | else if (!add || add == noexcept_false_spec) | |
2689 | return add; | |
10261728 | 2690 | |
b273cdb1 JM |
2691 | /* noexcept(true) and throw() are stricter than anything else. |
2692 | As above, prefer the more recent one (LIST). */ | |
2693 | if (nothrow_spec_p_uninst (add)) | |
03378143 | 2694 | return list; |
b273cdb1 | 2695 | |
b15ea309 JM |
2696 | /* Two implicit noexcept specs (e.g. on a destructor) are equivalent. */ |
2697 | if (UNEVALUATED_NOEXCEPT_SPEC_P (add) | |
2698 | && UNEVALUATED_NOEXCEPT_SPEC_P (list)) | |
2699 | return list; | |
2700 | /* We should have instantiated other deferred noexcept specs by now. */ | |
2701 | gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (add)); | |
2702 | ||
2703 | if (nothrow_spec_p_uninst (list)) | |
247078ec | 2704 | return add; |
b15ea309 JM |
2705 | noex = TREE_PURPOSE (list); |
2706 | gcc_checking_assert (!TREE_PURPOSE (add) | |
f9bf89bb | 2707 | || errorcount || !flag_exceptions |
b15ea309 | 2708 | || cp_tree_equal (noex, TREE_PURPOSE (add))); |
b273cdb1 JM |
2709 | |
2710 | /* Combine the dynamic-exception-specifiers, if any. */ | |
2711 | orig_list = list; | |
2712 | for (; add && TREE_VALUE (add); add = TREE_CHAIN (add)) | |
03378143 | 2713 | { |
b273cdb1 JM |
2714 | tree spec = TREE_VALUE (add); |
2715 | tree probe; | |
c8094d83 | 2716 | |
b273cdb1 JM |
2717 | for (probe = orig_list; probe && TREE_VALUE (probe); |
2718 | probe = TREE_CHAIN (probe)) | |
2719 | if (same_type_p (TREE_VALUE (probe), spec)) | |
2720 | break; | |
2721 | if (!probe) | |
0cbd7506 | 2722 | { |
b273cdb1 JM |
2723 | spec = build_tree_list (NULL_TREE, spec); |
2724 | TREE_CHAIN (spec) = list; | |
2725 | list = spec; | |
0cbd7506 | 2726 | } |
03378143 | 2727 | } |
b273cdb1 JM |
2728 | |
2729 | /* Keep the noexcept-specifier at the beginning of the list. */ | |
2730 | if (noex != TREE_PURPOSE (list)) | |
2731 | list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list)); | |
2732 | ||
03378143 NS |
2733 | return list; |
2734 | } | |
5aa3396c JM |
2735 | |
2736 | /* Subroutine of build_call. Ensure that each of the types in the | |
2737 | exception specification is complete. Technically, 15.4/1 says that | |
2738 | they need to be complete when we see a declaration of the function, | |
2739 | but we should be able to get away with only requiring this when the | |
2740 | function is defined or called. See also add_exception_specifier. */ | |
2741 | ||
2742 | void | |
0a8cb79e | 2743 | require_complete_eh_spec_types (tree fntype, tree decl) |
5aa3396c JM |
2744 | { |
2745 | tree raises; | |
2746 | /* Don't complain about calls to op new. */ | |
2747 | if (decl && DECL_ARTIFICIAL (decl)) | |
2748 | return; | |
2749 | for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises; | |
2750 | raises = TREE_CHAIN (raises)) | |
2751 | { | |
2752 | tree type = TREE_VALUE (raises); | |
2753 | if (type && !COMPLETE_TYPE_P (type)) | |
2754 | { | |
2755 | if (decl) | |
2756 | error | |
a82e1a7d | 2757 | ("call to function %qD which throws incomplete type %q#T", |
5aa3396c JM |
2758 | decl, type); |
2759 | else | |
a82e1a7d | 2760 | error ("call to function which throws incomplete type %q#T", |
5aa3396c JM |
2761 | decl); |
2762 | } | |
2763 | } | |
2764 | } | |
6ffbf87c JM |
2765 | |
2766 | /* Record that any TARGET_EXPR in T are going to be elided in | |
2767 | cp_gimplify_init_expr (or sooner). */ | |
2768 | ||
2769 | void | |
2770 | set_target_expr_eliding (tree t) | |
2771 | { | |
2772 | if (!t) | |
2773 | return; | |
2774 | switch (TREE_CODE (t)) | |
2775 | { | |
2776 | case TARGET_EXPR: | |
2777 | TARGET_EXPR_ELIDING_P (t) = true; | |
2778 | break; | |
2779 | case COMPOUND_EXPR: | |
2780 | set_target_expr_eliding (TREE_OPERAND (t, 1)); | |
2781 | break; | |
2782 | case COND_EXPR: | |
2783 | set_target_expr_eliding (TREE_OPERAND (t, 1)); | |
2784 | set_target_expr_eliding (TREE_OPERAND (t, 2)); | |
2785 | break; | |
2786 | ||
2787 | default: | |
2788 | break; | |
2789 | } | |
2790 | } | |
2791 | ||
2792 | /* Call the above in the process of building an INIT_EXPR. */ | |
2793 | ||
2794 | tree | |
2795 | cp_build_init_expr (location_t loc, tree target, tree init) | |
2796 | { | |
2797 | set_target_expr_eliding (init); | |
2798 | tree ie = build2_loc (loc, INIT_EXPR, TREE_TYPE (target), | |
2799 | target, init); | |
2800 | TREE_SIDE_EFFECTS (ie) = true; | |
2801 | return ie; | |
2802 | } |