annotate gcc/cp/typeck2.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Report error messages, build initializers, and perform
kono
parents:
diff changeset
2 some front-end optimizations for C++ compiler.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3 Copyright (C) 1987-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
4 Hacked by Michael Tiemann (tiemann@cygnus.com)
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
9 it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
10 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
11 any later version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
16 GNU General Public License for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22
kono
parents:
diff changeset
23 /* This file is part of the C++ front end.
kono
parents:
diff changeset
24 It contains routines to build C++ expressions given their operands,
kono
parents:
diff changeset
25 including computing the types of the result, C and C++ specific error
kono
parents:
diff changeset
26 checks, and some optimization. */
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #include "config.h"
kono
parents:
diff changeset
29 #include "system.h"
kono
parents:
diff changeset
30 #include "coretypes.h"
kono
parents:
diff changeset
31 #include "cp-tree.h"
kono
parents:
diff changeset
32 #include "stor-layout.h"
kono
parents:
diff changeset
33 #include "varasm.h"
kono
parents:
diff changeset
34 #include "intl.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
35 #include "gcc-rich-location.h"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
36 #include "target.h"
111
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 static tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
39 process_init_constructor (tree type, tree init, int nested, int flags,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 tsubst_flags_t complain);
111
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 /* Print an error message stemming from an attempt to use
kono
parents:
diff changeset
44 BASETYPE as a base class for TYPE. */
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 tree
kono
parents:
diff changeset
47 error_not_base_type (tree basetype, tree type)
kono
parents:
diff changeset
48 {
kono
parents:
diff changeset
49 if (TREE_CODE (basetype) == FUNCTION_DECL)
kono
parents:
diff changeset
50 basetype = DECL_CONTEXT (basetype);
kono
parents:
diff changeset
51 error ("type %qT is not a base type for type %qT", basetype, type);
kono
parents:
diff changeset
52 return error_mark_node;
kono
parents:
diff changeset
53 }
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 tree
kono
parents:
diff changeset
56 binfo_or_else (tree base, tree type)
kono
parents:
diff changeset
57 {
kono
parents:
diff changeset
58 tree binfo = lookup_base (type, base, ba_unique,
kono
parents:
diff changeset
59 NULL, tf_warning_or_error);
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 if (binfo == error_mark_node)
kono
parents:
diff changeset
62 return NULL_TREE;
kono
parents:
diff changeset
63 else if (!binfo)
kono
parents:
diff changeset
64 error_not_base_type (base, type);
kono
parents:
diff changeset
65 return binfo;
kono
parents:
diff changeset
66 }
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 /* According to ARM $7.1.6, "A `const' object may be initialized, but its
kono
parents:
diff changeset
69 value may not be changed thereafter. */
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
111
kono
parents:
diff changeset
73 {
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 /* This macro is used to emit diagnostics to ensure that all format
kono
parents:
diff changeset
76 strings are complete sentences, visible to gettext and checked at
kono
parents:
diff changeset
77 compile time. */
kono
parents:
diff changeset
78
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 #define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG) \
111
kono
parents:
diff changeset
80 do { \
kono
parents:
diff changeset
81 switch (errstring) \
kono
parents:
diff changeset
82 { \
kono
parents:
diff changeset
83 case lv_assign: \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 error_at (LOC, AS, ARG); \
111
kono
parents:
diff changeset
85 break; \
kono
parents:
diff changeset
86 case lv_asm: \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 error_at (LOC, ASM, ARG); \
111
kono
parents:
diff changeset
88 break; \
kono
parents:
diff changeset
89 case lv_increment: \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 error_at (LOC, IN, ARG); \
111
kono
parents:
diff changeset
91 break; \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 case lv_decrement: \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 error_at (LOC, DE, ARG); \
111
kono
parents:
diff changeset
94 break; \
kono
parents:
diff changeset
95 default: \
kono
parents:
diff changeset
96 gcc_unreachable (); \
kono
parents:
diff changeset
97 } \
kono
parents:
diff changeset
98 } while (0)
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 /* Handle C++-specific things first. */
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 if (VAR_P (arg)
kono
parents:
diff changeset
103 && DECL_LANG_SPECIFIC (arg)
kono
parents:
diff changeset
104 && DECL_IN_AGGR_P (arg)
kono
parents:
diff changeset
105 && !TREE_STATIC (arg))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 ERROR_FOR_ASSIGNMENT (loc,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 G_("assignment of constant field %qD"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 G_("constant field %qD used as %<asm%> output"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 G_("increment of constant field %qD"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 G_("decrement of constant field %qD"),
111
kono
parents:
diff changeset
111 arg);
kono
parents:
diff changeset
112 else if (INDIRECT_REF_P (arg)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
111
kono
parents:
diff changeset
114 && (VAR_P (TREE_OPERAND (arg, 0))
kono
parents:
diff changeset
115 || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 ERROR_FOR_ASSIGNMENT (loc,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 G_("assignment of read-only reference %qD"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 G_("read-only reference %qD used as %<asm%> output"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 G_("increment of read-only reference %qD"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 G_("decrement of read-only reference %qD"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 TREE_OPERAND (arg, 0));
111
kono
parents:
diff changeset
122 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 readonly_error (loc, arg, errstring);
111
kono
parents:
diff changeset
124 }
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 /* Structure that holds information about declarations whose type was
kono
parents:
diff changeset
127 incomplete and we could not check whether it was abstract or not. */
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 struct GTY((chain_next ("%h.next"), for_user)) pending_abstract_type {
kono
parents:
diff changeset
130 /* Declaration which we are checking for abstractness. It is either
kono
parents:
diff changeset
131 a DECL node, or an IDENTIFIER_NODE if we do not have a full
kono
parents:
diff changeset
132 declaration available. */
kono
parents:
diff changeset
133 tree decl;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 /* Type which will be checked for abstractness. */
kono
parents:
diff changeset
136 tree type;
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 /* Kind of use in an unnamed declarator. */
kono
parents:
diff changeset
139 enum abstract_class_use use;
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 /* Position of the declaration. This is only needed for IDENTIFIER_NODEs,
kono
parents:
diff changeset
142 because DECLs already carry locus information. */
kono
parents:
diff changeset
143 location_t locus;
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 /* Link to the next element in list. */
kono
parents:
diff changeset
146 struct pending_abstract_type* next;
kono
parents:
diff changeset
147 };
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 struct abstract_type_hasher : ggc_ptr_hash<pending_abstract_type>
kono
parents:
diff changeset
150 {
kono
parents:
diff changeset
151 typedef tree compare_type;
kono
parents:
diff changeset
152 static hashval_t hash (pending_abstract_type *);
kono
parents:
diff changeset
153 static bool equal (pending_abstract_type *, tree);
kono
parents:
diff changeset
154 };
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 /* Compute the hash value of the node VAL. This function is used by the
kono
parents:
diff changeset
157 hash table abstract_pending_vars. */
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 hashval_t
kono
parents:
diff changeset
160 abstract_type_hasher::hash (pending_abstract_type *pat)
kono
parents:
diff changeset
161 {
kono
parents:
diff changeset
162 return (hashval_t) TYPE_UID (pat->type);
kono
parents:
diff changeset
163 }
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 /* Compare node VAL1 with the type VAL2. This function is used by the
kono
parents:
diff changeset
167 hash table abstract_pending_vars. */
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 bool
kono
parents:
diff changeset
170 abstract_type_hasher::equal (pending_abstract_type *pat1, tree type2)
kono
parents:
diff changeset
171 {
kono
parents:
diff changeset
172 return (pat1->type == type2);
kono
parents:
diff changeset
173 }
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 /* Hash table that maintains pending_abstract_type nodes, for which we still
kono
parents:
diff changeset
176 need to check for type abstractness. The key of the table is the type
kono
parents:
diff changeset
177 of the declaration. */
kono
parents:
diff changeset
178 static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 /* This function is called after TYPE is completed, and will check if there
kono
parents:
diff changeset
183 are pending declarations for which we still need to verify the abstractness
kono
parents:
diff changeset
184 of TYPE, and emit a diagnostic (through abstract_virtuals_error) if TYPE
kono
parents:
diff changeset
185 turned out to be incomplete. */
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 void
kono
parents:
diff changeset
188 complete_type_check_abstract (tree type)
kono
parents:
diff changeset
189 {
kono
parents:
diff changeset
190 struct pending_abstract_type *pat;
kono
parents:
diff changeset
191 location_t cur_loc = input_location;
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 gcc_assert (COMPLETE_TYPE_P (type));
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 if (!abstract_pending_vars)
kono
parents:
diff changeset
196 return;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 /* Retrieve the list of pending declarations for this type. */
kono
parents:
diff changeset
199 pending_abstract_type **slot
kono
parents:
diff changeset
200 = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
kono
parents:
diff changeset
201 NO_INSERT);
kono
parents:
diff changeset
202 if (!slot)
kono
parents:
diff changeset
203 return;
kono
parents:
diff changeset
204 pat = *slot;
kono
parents:
diff changeset
205 gcc_assert (pat);
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 /* If the type is not abstract, do not do anything. */
kono
parents:
diff changeset
208 if (CLASSTYPE_PURE_VIRTUALS (type))
kono
parents:
diff changeset
209 {
kono
parents:
diff changeset
210 struct pending_abstract_type *prev = 0, *next;
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 /* Reverse the list to emit the errors in top-down order. */
kono
parents:
diff changeset
213 for (; pat; pat = next)
kono
parents:
diff changeset
214 {
kono
parents:
diff changeset
215 next = pat->next;
kono
parents:
diff changeset
216 pat->next = prev;
kono
parents:
diff changeset
217 prev = pat;
kono
parents:
diff changeset
218 }
kono
parents:
diff changeset
219 pat = prev;
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 /* Go through the list, and call abstract_virtuals_error for each
kono
parents:
diff changeset
222 element: it will issue a diagnostic if the type is abstract. */
kono
parents:
diff changeset
223 while (pat)
kono
parents:
diff changeset
224 {
kono
parents:
diff changeset
225 gcc_assert (type == pat->type);
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 /* Tweak input_location so that the diagnostic appears at the correct
kono
parents:
diff changeset
228 location. Notice that this is only needed if the decl is an
kono
parents:
diff changeset
229 IDENTIFIER_NODE. */
kono
parents:
diff changeset
230 input_location = pat->locus;
kono
parents:
diff changeset
231 abstract_virtuals_error_sfinae (pat->decl, pat->type, pat->use,
kono
parents:
diff changeset
232 tf_warning_or_error);
kono
parents:
diff changeset
233 pat = pat->next;
kono
parents:
diff changeset
234 }
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 abstract_pending_vars->clear_slot (slot);
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 input_location = cur_loc;
kono
parents:
diff changeset
240 }
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 /* If TYPE has abstract virtual functions, issue an error about trying
kono
parents:
diff changeset
244 to create an object of that type. DECL is the object declared, or
kono
parents:
diff changeset
245 NULL_TREE if the declaration is unavailable, in which case USE specifies
kono
parents:
diff changeset
246 the kind of invalid use. Returns 1 if an error occurred; zero if
kono
parents:
diff changeset
247 all was well. */
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 static int
kono
parents:
diff changeset
250 abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
kono
parents:
diff changeset
251 tsubst_flags_t complain)
kono
parents:
diff changeset
252 {
kono
parents:
diff changeset
253 vec<tree, va_gc> *pure;
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 /* This function applies only to classes. Any other entity can never
kono
parents:
diff changeset
256 be abstract. */
kono
parents:
diff changeset
257 if (!CLASS_TYPE_P (type))
kono
parents:
diff changeset
258 return 0;
kono
parents:
diff changeset
259 type = TYPE_MAIN_VARIANT (type);
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 #if 0
kono
parents:
diff changeset
262 /* Instantiation here seems to be required by the standard,
kono
parents:
diff changeset
263 but breaks e.g. boost::bind. FIXME! */
kono
parents:
diff changeset
264 /* In SFINAE, non-N3276 context, force instantiation. */
kono
parents:
diff changeset
265 if (!(complain & (tf_error|tf_decltype)))
kono
parents:
diff changeset
266 complete_type (type);
kono
parents:
diff changeset
267 #endif
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 /* If the type is incomplete, we register it within a hash table,
kono
parents:
diff changeset
270 so that we can check again once it is completed. This makes sense
kono
parents:
diff changeset
271 only for objects for which we have a declaration or at least a
kono
parents:
diff changeset
272 name. */
kono
parents:
diff changeset
273 if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
kono
parents:
diff changeset
274 {
kono
parents:
diff changeset
275 struct pending_abstract_type *pat;
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 if (!abstract_pending_vars)
kono
parents:
diff changeset
280 abstract_pending_vars
kono
parents:
diff changeset
281 = hash_table<abstract_type_hasher>::create_ggc (31);
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 pending_abstract_type **slot
kono
parents:
diff changeset
284 = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
kono
parents:
diff changeset
285 INSERT);
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 pat = ggc_alloc<pending_abstract_type> ();
kono
parents:
diff changeset
288 pat->type = type;
kono
parents:
diff changeset
289 pat->decl = decl;
kono
parents:
diff changeset
290 pat->use = use;
kono
parents:
diff changeset
291 pat->locus = ((decl && DECL_P (decl))
kono
parents:
diff changeset
292 ? DECL_SOURCE_LOCATION (decl)
kono
parents:
diff changeset
293 : input_location);
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 pat->next = *slot;
kono
parents:
diff changeset
296 *slot = pat;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 return 0;
kono
parents:
diff changeset
299 }
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 if (!TYPE_SIZE (type))
kono
parents:
diff changeset
302 /* TYPE is being defined, and during that time
kono
parents:
diff changeset
303 CLASSTYPE_PURE_VIRTUALS holds the inline friends. */
kono
parents:
diff changeset
304 return 0;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 pure = CLASSTYPE_PURE_VIRTUALS (type);
kono
parents:
diff changeset
307 if (!pure)
kono
parents:
diff changeset
308 return 0;
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 if (!(complain & tf_error))
kono
parents:
diff changeset
311 return 1;
kono
parents:
diff changeset
312
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313 auto_diagnostic_group d;
111
kono
parents:
diff changeset
314 if (decl)
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 if (VAR_P (decl))
kono
parents:
diff changeset
317 error ("cannot declare variable %q+D to be of abstract "
kono
parents:
diff changeset
318 "type %qT", decl, type);
kono
parents:
diff changeset
319 else if (TREE_CODE (decl) == PARM_DECL)
kono
parents:
diff changeset
320 {
kono
parents:
diff changeset
321 if (DECL_NAME (decl))
kono
parents:
diff changeset
322 error ("cannot declare parameter %q+D to be of abstract type %qT",
kono
parents:
diff changeset
323 decl, type);
kono
parents:
diff changeset
324 else
kono
parents:
diff changeset
325 error ("cannot declare parameter to be of abstract type %qT",
kono
parents:
diff changeset
326 type);
kono
parents:
diff changeset
327 }
kono
parents:
diff changeset
328 else if (TREE_CODE (decl) == FIELD_DECL)
kono
parents:
diff changeset
329 error ("cannot declare field %q+D to be of abstract type %qT",
kono
parents:
diff changeset
330 decl, type);
kono
parents:
diff changeset
331 else if (TREE_CODE (decl) == FUNCTION_DECL
kono
parents:
diff changeset
332 && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
kono
parents:
diff changeset
333 error ("invalid abstract return type for member function %q+#D", decl);
kono
parents:
diff changeset
334 else if (TREE_CODE (decl) == FUNCTION_DECL)
kono
parents:
diff changeset
335 error ("invalid abstract return type for function %q+#D", decl);
kono
parents:
diff changeset
336 else if (identifier_p (decl))
kono
parents:
diff changeset
337 /* Here we do not have location information. */
kono
parents:
diff changeset
338 error ("invalid abstract type %qT for %qE", type, decl);
kono
parents:
diff changeset
339 else
kono
parents:
diff changeset
340 error ("invalid abstract type for %q+D", decl);
kono
parents:
diff changeset
341 }
kono
parents:
diff changeset
342 else switch (use)
kono
parents:
diff changeset
343 {
kono
parents:
diff changeset
344 case ACU_ARRAY:
kono
parents:
diff changeset
345 error ("creating array of %qT, which is an abstract class type", type);
kono
parents:
diff changeset
346 break;
kono
parents:
diff changeset
347 case ACU_CAST:
kono
parents:
diff changeset
348 error ("invalid cast to abstract class type %qT", type);
kono
parents:
diff changeset
349 break;
kono
parents:
diff changeset
350 case ACU_NEW:
kono
parents:
diff changeset
351 error ("invalid new-expression of abstract class type %qT", type);
kono
parents:
diff changeset
352 break;
kono
parents:
diff changeset
353 case ACU_RETURN:
kono
parents:
diff changeset
354 error ("invalid abstract return type %qT", type);
kono
parents:
diff changeset
355 break;
kono
parents:
diff changeset
356 case ACU_PARM:
kono
parents:
diff changeset
357 error ("invalid abstract parameter type %qT", type);
kono
parents:
diff changeset
358 break;
kono
parents:
diff changeset
359 case ACU_THROW:
kono
parents:
diff changeset
360 error ("expression of abstract class type %qT cannot "
kono
parents:
diff changeset
361 "be used in throw-expression", type);
kono
parents:
diff changeset
362 break;
kono
parents:
diff changeset
363 case ACU_CATCH:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
364 error ("cannot declare %<catch%> parameter to be of abstract "
111
kono
parents:
diff changeset
365 "class type %qT", type);
kono
parents:
diff changeset
366 break;
kono
parents:
diff changeset
367 default:
kono
parents:
diff changeset
368 error ("cannot allocate an object of abstract type %qT", type);
kono
parents:
diff changeset
369 }
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 /* Only go through this once. */
kono
parents:
diff changeset
372 if (pure->length ())
kono
parents:
diff changeset
373 {
kono
parents:
diff changeset
374 unsigned ix;
kono
parents:
diff changeset
375 tree fn;
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
kono
parents:
diff changeset
378 " because the following virtual functions are pure within %qT:",
kono
parents:
diff changeset
379 type);
kono
parents:
diff changeset
380
kono
parents:
diff changeset
381 FOR_EACH_VEC_ELT (*pure, ix, fn)
kono
parents:
diff changeset
382 if (! DECL_CLONED_FUNCTION_P (fn)
kono
parents:
diff changeset
383 || DECL_COMPLETE_DESTRUCTOR_P (fn))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 inform (DECL_SOURCE_LOCATION (fn), " %#qD", fn);
111
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 /* Now truncate the vector. This leaves it non-null, so we know
kono
parents:
diff changeset
387 there are pure virtuals, but empty so we don't list them out
kono
parents:
diff changeset
388 again. */
kono
parents:
diff changeset
389 pure->truncate (0);
kono
parents:
diff changeset
390 }
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 return 1;
kono
parents:
diff changeset
393 }
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 int
kono
parents:
diff changeset
396 abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain)
kono
parents:
diff changeset
397 {
kono
parents:
diff changeset
398 return abstract_virtuals_error_sfinae (decl, type, ACU_UNKNOWN, complain);
kono
parents:
diff changeset
399 }
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 int
kono
parents:
diff changeset
402 abstract_virtuals_error_sfinae (abstract_class_use use, tree type,
kono
parents:
diff changeset
403 tsubst_flags_t complain)
kono
parents:
diff changeset
404 {
kono
parents:
diff changeset
405 return abstract_virtuals_error_sfinae (NULL_TREE, type, use, complain);
kono
parents:
diff changeset
406 }
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 /* Wrapper for the above function in the common case of wanting errors. */
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 int
kono
parents:
diff changeset
412 abstract_virtuals_error (tree decl, tree type)
kono
parents:
diff changeset
413 {
kono
parents:
diff changeset
414 return abstract_virtuals_error_sfinae (decl, type, tf_warning_or_error);
kono
parents:
diff changeset
415 }
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 int
kono
parents:
diff changeset
418 abstract_virtuals_error (abstract_class_use use, tree type)
kono
parents:
diff changeset
419 {
kono
parents:
diff changeset
420 return abstract_virtuals_error_sfinae (use, type, tf_warning_or_error);
kono
parents:
diff changeset
421 }
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 /* Print an inform about the declaration of the incomplete type TYPE. */
kono
parents:
diff changeset
424
kono
parents:
diff changeset
425 void
kono
parents:
diff changeset
426 cxx_incomplete_type_inform (const_tree type)
kono
parents:
diff changeset
427 {
kono
parents:
diff changeset
428 if (!TYPE_MAIN_DECL (type))
kono
parents:
diff changeset
429 return;
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
kono
parents:
diff changeset
432 tree ptype = strip_top_quals (CONST_CAST_TREE (type));
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 if (current_class_type
kono
parents:
diff changeset
435 && TYPE_BEING_DEFINED (current_class_type)
kono
parents:
diff changeset
436 && same_type_p (ptype, current_class_type))
kono
parents:
diff changeset
437 inform (loc, "definition of %q#T is not complete until "
kono
parents:
diff changeset
438 "the closing brace", ptype);
kono
parents:
diff changeset
439 else if (!TYPE_TEMPLATE_INFO (ptype))
kono
parents:
diff changeset
440 inform (loc, "forward declaration of %q#T", ptype);
kono
parents:
diff changeset
441 else
kono
parents:
diff changeset
442 inform (loc, "declaration of %q#T", ptype);
kono
parents:
diff changeset
443 }
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 /* Print an error message for invalid use of an incomplete type.
kono
parents:
diff changeset
446 VALUE is the expression that was used (or 0 if that isn't known)
kono
parents:
diff changeset
447 and TYPE is the type that was invalid. DIAG_KIND indicates the
kono
parents:
diff changeset
448 type of diagnostic (see diagnostic.def). */
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 void
kono
parents:
diff changeset
451 cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
kono
parents:
diff changeset
452 const_tree type, diagnostic_t diag_kind)
kono
parents:
diff changeset
453 {
kono
parents:
diff changeset
454 bool is_decl = false, complained = false;
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 gcc_assert (diag_kind == DK_WARNING
kono
parents:
diff changeset
457 || diag_kind == DK_PEDWARN
kono
parents:
diff changeset
458 || diag_kind == DK_ERROR);
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 /* Avoid duplicate error message. */
kono
parents:
diff changeset
461 if (TREE_CODE (type) == ERROR_MARK)
kono
parents:
diff changeset
462 return;
kono
parents:
diff changeset
463
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
464 if (value)
111
kono
parents:
diff changeset
465 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
466 STRIP_ANY_LOCATION_WRAPPER (value);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
467
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
468 if (VAR_P (value)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
469 || TREE_CODE (value) == PARM_DECL
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
470 || TREE_CODE (value) == FIELD_DECL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
471 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
472 complained = emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (value), 0,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
473 "%qD has incomplete type", value);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
474 is_decl = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
475 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
476 }
111
kono
parents:
diff changeset
477 retry:
kono
parents:
diff changeset
478 /* We must print an error message. Be clever about what it says. */
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 switch (TREE_CODE (type))
kono
parents:
diff changeset
481 {
kono
parents:
diff changeset
482 case RECORD_TYPE:
kono
parents:
diff changeset
483 case UNION_TYPE:
kono
parents:
diff changeset
484 case ENUMERAL_TYPE:
kono
parents:
diff changeset
485 if (!is_decl)
kono
parents:
diff changeset
486 complained = emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
487 "invalid use of incomplete type %q#T",
kono
parents:
diff changeset
488 type);
kono
parents:
diff changeset
489 if (complained)
kono
parents:
diff changeset
490 cxx_incomplete_type_inform (type);
kono
parents:
diff changeset
491 break;
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 case VOID_TYPE:
kono
parents:
diff changeset
494 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
495 "invalid use of %qT", type);
kono
parents:
diff changeset
496 break;
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 case ARRAY_TYPE:
kono
parents:
diff changeset
499 if (TYPE_DOMAIN (type))
kono
parents:
diff changeset
500 {
kono
parents:
diff changeset
501 type = TREE_TYPE (type);
kono
parents:
diff changeset
502 goto retry;
kono
parents:
diff changeset
503 }
kono
parents:
diff changeset
504 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
505 "invalid use of array with unspecified bounds");
kono
parents:
diff changeset
506 break;
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 case OFFSET_TYPE:
kono
parents:
diff changeset
509 bad_member:
kono
parents:
diff changeset
510 {
kono
parents:
diff changeset
511 tree member = TREE_OPERAND (value, 1);
kono
parents:
diff changeset
512 if (is_overloaded_fn (member))
kono
parents:
diff changeset
513 member = get_first_fn (member);
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 if (DECL_FUNCTION_MEMBER_P (member)
kono
parents:
diff changeset
516 && ! flag_ms_extensions)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
517 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
518 gcc_rich_location richloc (loc);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
519 /* If "member" has no arguments (other than "this"), then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
520 add a fix-it hint. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
521 if (type_num_arguments (TREE_TYPE (member)) == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
522 richloc.add_fixit_insert_after ("()");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
523 emit_diagnostic (diag_kind, &richloc, 0,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
524 "invalid use of member function %qD "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
525 "(did you forget the %<()%> ?)", member);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
526 }
111
kono
parents:
diff changeset
527 else
kono
parents:
diff changeset
528 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
529 "invalid use of member %qD "
kono
parents:
diff changeset
530 "(did you forget the %<&%> ?)", member);
kono
parents:
diff changeset
531 }
kono
parents:
diff changeset
532 break;
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 case TEMPLATE_TYPE_PARM:
kono
parents:
diff changeset
535 if (is_auto (type))
kono
parents:
diff changeset
536 {
kono
parents:
diff changeset
537 if (CLASS_PLACEHOLDER_TEMPLATE (type))
kono
parents:
diff changeset
538 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
539 "invalid use of placeholder %qT", type);
kono
parents:
diff changeset
540 else
kono
parents:
diff changeset
541 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
542 "invalid use of %qT", type);
kono
parents:
diff changeset
543 }
kono
parents:
diff changeset
544 else
kono
parents:
diff changeset
545 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
546 "invalid use of template type parameter %qT", type);
kono
parents:
diff changeset
547 break;
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 case BOUND_TEMPLATE_TEMPLATE_PARM:
kono
parents:
diff changeset
550 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
551 "invalid use of template template parameter %qT",
kono
parents:
diff changeset
552 TYPE_NAME (type));
kono
parents:
diff changeset
553 break;
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 case TYPENAME_TYPE:
kono
parents:
diff changeset
556 case DECLTYPE_TYPE:
kono
parents:
diff changeset
557 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
558 "invalid use of dependent type %qT", type);
kono
parents:
diff changeset
559 break;
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 case LANG_TYPE:
kono
parents:
diff changeset
562 if (type == init_list_type_node)
kono
parents:
diff changeset
563 {
kono
parents:
diff changeset
564 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
565 "invalid use of brace-enclosed initializer list");
kono
parents:
diff changeset
566 break;
kono
parents:
diff changeset
567 }
kono
parents:
diff changeset
568 gcc_assert (type == unknown_type_node);
kono
parents:
diff changeset
569 if (value && TREE_CODE (value) == COMPONENT_REF)
kono
parents:
diff changeset
570 goto bad_member;
kono
parents:
diff changeset
571 else if (value && TREE_CODE (value) == ADDR_EXPR)
kono
parents:
diff changeset
572 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
573 "address of overloaded function with no contextual "
kono
parents:
diff changeset
574 "type information");
kono
parents:
diff changeset
575 else if (value && TREE_CODE (value) == OVERLOAD)
kono
parents:
diff changeset
576 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
577 "overloaded function with no contextual type information");
kono
parents:
diff changeset
578 else
kono
parents:
diff changeset
579 emit_diagnostic (diag_kind, loc, 0,
kono
parents:
diff changeset
580 "insufficient contextual information to determine type");
kono
parents:
diff changeset
581 break;
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 default:
kono
parents:
diff changeset
584 gcc_unreachable ();
kono
parents:
diff changeset
585 }
kono
parents:
diff changeset
586 }
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 /* Print an error message for invalid use of an incomplete type.
kono
parents:
diff changeset
589 VALUE is the expression that was used (or 0 if that isn't known)
kono
parents:
diff changeset
590 and TYPE is the type that was invalid. */
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 void
kono
parents:
diff changeset
593 cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type)
kono
parents:
diff changeset
594 {
kono
parents:
diff changeset
595 cxx_incomplete_type_diagnostic (loc, value, type, DK_ERROR);
kono
parents:
diff changeset
596 }
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 /* The recursive part of split_nonconstant_init. DEST is an lvalue
kono
parents:
diff changeset
600 expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
kono
parents:
diff changeset
601 Return true if the whole of the value was initialized by the
kono
parents:
diff changeset
602 generated statements. */
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
605 split_nonconstant_init_1 (tree dest, tree init, bool nested)
111
kono
parents:
diff changeset
606 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
607 unsigned HOST_WIDE_INT idx, tidx = HOST_WIDE_INT_M1U;
111
kono
parents:
diff changeset
608 tree field_index, value;
kono
parents:
diff changeset
609 tree type = TREE_TYPE (dest);
kono
parents:
diff changeset
610 tree inner_type = NULL;
kono
parents:
diff changeset
611 bool array_type_p = false;
kono
parents:
diff changeset
612 bool complete_p = true;
kono
parents:
diff changeset
613 HOST_WIDE_INT num_split_elts = 0;
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 switch (TREE_CODE (type))
kono
parents:
diff changeset
616 {
kono
parents:
diff changeset
617 case ARRAY_TYPE:
kono
parents:
diff changeset
618 inner_type = TREE_TYPE (type);
kono
parents:
diff changeset
619 array_type_p = true;
kono
parents:
diff changeset
620 if ((TREE_SIDE_EFFECTS (init)
kono
parents:
diff changeset
621 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 || vla_type_p (type))
111
kono
parents:
diff changeset
623 {
kono
parents:
diff changeset
624 /* For an array, we only need/want a single cleanup region rather
kono
parents:
diff changeset
625 than one per element. */
kono
parents:
diff changeset
626 tree code = build_vec_init (dest, NULL_TREE, init, false, 1,
kono
parents:
diff changeset
627 tf_warning_or_error);
kono
parents:
diff changeset
628 add_stmt (code);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
629 if (nested)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
630 /* Also clean up the whole array if something later in an enclosing
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
631 init-list throws. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
632 if (tree cleanup = cxx_maybe_build_cleanup (dest,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
633 tf_warning_or_error))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
634 finish_eh_cleanup (cleanup);
111
kono
parents:
diff changeset
635 return true;
kono
parents:
diff changeset
636 }
kono
parents:
diff changeset
637 /* FALLTHRU */
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 case RECORD_TYPE:
kono
parents:
diff changeset
640 case UNION_TYPE:
kono
parents:
diff changeset
641 case QUAL_UNION_TYPE:
kono
parents:
diff changeset
642 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
kono
parents:
diff changeset
643 field_index, value)
kono
parents:
diff changeset
644 {
kono
parents:
diff changeset
645 /* The current implementation of this algorithm assumes that
kono
parents:
diff changeset
646 the field was set for all the elements. This is usually done
kono
parents:
diff changeset
647 by process_init_constructor. */
kono
parents:
diff changeset
648 gcc_assert (field_index);
kono
parents:
diff changeset
649
kono
parents:
diff changeset
650 if (!array_type_p)
kono
parents:
diff changeset
651 inner_type = TREE_TYPE (field_index);
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 if (TREE_CODE (value) == CONSTRUCTOR)
kono
parents:
diff changeset
654 {
kono
parents:
diff changeset
655 tree sub;
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 if (array_type_p)
kono
parents:
diff changeset
658 sub = build4 (ARRAY_REF, inner_type, dest, field_index,
kono
parents:
diff changeset
659 NULL_TREE, NULL_TREE);
kono
parents:
diff changeset
660 else
kono
parents:
diff changeset
661 sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
kono
parents:
diff changeset
662 NULL_TREE);
kono
parents:
diff changeset
663
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
664 if (!split_nonconstant_init_1 (sub, value, true))
111
kono
parents:
diff changeset
665 complete_p = false;
kono
parents:
diff changeset
666 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
667 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
668 /* Mark element for removal. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
669 CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
670 if (idx < tidx)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
671 tidx = idx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
672 num_split_elts++;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
673 }
111
kono
parents:
diff changeset
674 }
kono
parents:
diff changeset
675 else if (!initializer_constant_valid_p (value, inner_type))
kono
parents:
diff changeset
676 {
kono
parents:
diff changeset
677 tree code;
kono
parents:
diff changeset
678 tree sub;
kono
parents:
diff changeset
679
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
680 /* Mark element for removal. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
681 CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
682 if (idx < tidx)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
683 tidx = idx;
111
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 if (TREE_CODE (field_index) == RANGE_EXPR)
kono
parents:
diff changeset
686 {
kono
parents:
diff changeset
687 /* Use build_vec_init to initialize a range. */
kono
parents:
diff changeset
688 tree low = TREE_OPERAND (field_index, 0);
kono
parents:
diff changeset
689 tree hi = TREE_OPERAND (field_index, 1);
kono
parents:
diff changeset
690 sub = build4 (ARRAY_REF, inner_type, dest, low,
kono
parents:
diff changeset
691 NULL_TREE, NULL_TREE);
kono
parents:
diff changeset
692 sub = cp_build_addr_expr (sub, tf_warning_or_error);
kono
parents:
diff changeset
693 tree max = size_binop (MINUS_EXPR, hi, low);
kono
parents:
diff changeset
694 code = build_vec_init (sub, max, value, false, 0,
kono
parents:
diff changeset
695 tf_warning_or_error);
kono
parents:
diff changeset
696 add_stmt (code);
kono
parents:
diff changeset
697 if (tree_fits_shwi_p (max))
kono
parents:
diff changeset
698 num_split_elts += tree_to_shwi (max);
kono
parents:
diff changeset
699 }
kono
parents:
diff changeset
700 else
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 if (array_type_p)
kono
parents:
diff changeset
703 sub = build4 (ARRAY_REF, inner_type, dest, field_index,
kono
parents:
diff changeset
704 NULL_TREE, NULL_TREE);
kono
parents:
diff changeset
705 else
kono
parents:
diff changeset
706 sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
kono
parents:
diff changeset
707 NULL_TREE);
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 code = build2 (INIT_EXPR, inner_type, sub, value);
kono
parents:
diff changeset
710 code = build_stmt (input_location, EXPR_STMT, code);
kono
parents:
diff changeset
711 code = maybe_cleanup_point_expr_void (code);
kono
parents:
diff changeset
712 add_stmt (code);
kono
parents:
diff changeset
713 if (tree cleanup
kono
parents:
diff changeset
714 = cxx_maybe_build_cleanup (sub, tf_warning_or_error))
kono
parents:
diff changeset
715 finish_eh_cleanup (cleanup);
kono
parents:
diff changeset
716 }
kono
parents:
diff changeset
717
kono
parents:
diff changeset
718 num_split_elts++;
kono
parents:
diff changeset
719 }
kono
parents:
diff changeset
720 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
721 if (num_split_elts == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
722 CONSTRUCTOR_ELTS (init)->ordered_remove (tidx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
723 else if (num_split_elts > 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
724 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
725 /* Perform the delayed ordered removal of non-constant elements
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
726 we split out. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
727 for (idx = tidx; idx < CONSTRUCTOR_NELTS (init); ++idx)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
728 if (CONSTRUCTOR_ELT (init, idx)->index == NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
729 ;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
730 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
731 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
732 *CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
733 ++tidx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
734 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
735 vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
736 }
111
kono
parents:
diff changeset
737 break;
kono
parents:
diff changeset
738
kono
parents:
diff changeset
739 case VECTOR_TYPE:
kono
parents:
diff changeset
740 if (!initializer_constant_valid_p (init, type))
kono
parents:
diff changeset
741 {
kono
parents:
diff changeset
742 tree code;
kono
parents:
diff changeset
743 tree cons = copy_node (init);
kono
parents:
diff changeset
744 CONSTRUCTOR_ELTS (init) = NULL;
kono
parents:
diff changeset
745 code = build2 (MODIFY_EXPR, type, dest, cons);
kono
parents:
diff changeset
746 code = build_stmt (input_location, EXPR_STMT, code);
kono
parents:
diff changeset
747 add_stmt (code);
kono
parents:
diff changeset
748 num_split_elts += CONSTRUCTOR_NELTS (init);
kono
parents:
diff changeset
749 }
kono
parents:
diff changeset
750 break;
kono
parents:
diff changeset
751
kono
parents:
diff changeset
752 default:
kono
parents:
diff changeset
753 gcc_unreachable ();
kono
parents:
diff changeset
754 }
kono
parents:
diff changeset
755
kono
parents:
diff changeset
756 /* The rest of the initializer is now a constant. */
kono
parents:
diff changeset
757 TREE_CONSTANT (init) = 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
758 TREE_SIDE_EFFECTS (init) = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
760 /* We didn't split out anything. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
761 if (num_split_elts == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
762 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
763
111
kono
parents:
diff changeset
764 return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
kono
parents:
diff changeset
765 num_split_elts, inner_type);
kono
parents:
diff changeset
766 }
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 /* A subroutine of store_init_value. Splits non-constant static
kono
parents:
diff changeset
769 initializer INIT into a constant part and generates code to
kono
parents:
diff changeset
770 perform the non-constant part of the initialization to DEST.
kono
parents:
diff changeset
771 Returns the code for the runtime init. */
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 tree
kono
parents:
diff changeset
774 split_nonconstant_init (tree dest, tree init)
kono
parents:
diff changeset
775 {
kono
parents:
diff changeset
776 tree code;
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 if (TREE_CODE (init) == TARGET_EXPR)
kono
parents:
diff changeset
779 init = TARGET_EXPR_INITIAL (init);
kono
parents:
diff changeset
780 if (TREE_CODE (init) == CONSTRUCTOR)
kono
parents:
diff changeset
781 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
782 init = cp_fully_fold_init (init);
111
kono
parents:
diff changeset
783 code = push_stmt_list ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
784 if (split_nonconstant_init_1 (dest, init, false))
111
kono
parents:
diff changeset
785 init = NULL_TREE;
kono
parents:
diff changeset
786 code = pop_stmt_list (code);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
787 if (VAR_P (dest) && !is_local_temp (dest))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
788 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
789 DECL_INITIAL (dest) = init;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
790 TREE_READONLY (dest) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
791 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
792 else if (init)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
793 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
794 tree ie = build2 (INIT_EXPR, void_type_node, dest, init);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
795 code = add_stmt_to_compound (ie, code);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
796 }
111
kono
parents:
diff changeset
797 }
kono
parents:
diff changeset
798 else if (TREE_CODE (init) == STRING_CST
kono
parents:
diff changeset
799 && array_of_runtime_bound_p (TREE_TYPE (dest)))
kono
parents:
diff changeset
800 code = build_vec_init (dest, NULL_TREE, init, /*value-init*/false,
kono
parents:
diff changeset
801 /*from array*/1, tf_warning_or_error);
kono
parents:
diff changeset
802 else
kono
parents:
diff changeset
803 code = build2 (INIT_EXPR, TREE_TYPE (dest), dest, init);
kono
parents:
diff changeset
804
kono
parents:
diff changeset
805 return code;
kono
parents:
diff changeset
806 }
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 /* Perform appropriate conversions on the initial value of a variable,
kono
parents:
diff changeset
809 store it in the declaration DECL,
kono
parents:
diff changeset
810 and print any error messages that are appropriate.
kono
parents:
diff changeset
811 If the init is invalid, store an ERROR_MARK.
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 C++: Note that INIT might be a TREE_LIST, which would mean that it is
kono
parents:
diff changeset
814 a base class initializer for some aggregate type, hopefully compatible
kono
parents:
diff changeset
815 with DECL. If INIT is a single element, and DECL is an aggregate
kono
parents:
diff changeset
816 type, we silently convert INIT into a TREE_LIST, allowing a constructor
kono
parents:
diff changeset
817 to be called.
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 If INIT is a TREE_LIST and there is no constructor, turn INIT
kono
parents:
diff changeset
820 into a CONSTRUCTOR and use standard initialization techniques.
kono
parents:
diff changeset
821 Perhaps a warning should be generated?
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 Returns code to be executed if initialization could not be performed
kono
parents:
diff changeset
824 for static variable. In that case, caller must emit the code. */
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 tree
kono
parents:
diff changeset
827 store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
kono
parents:
diff changeset
828 {
kono
parents:
diff changeset
829 tree value, type;
kono
parents:
diff changeset
830
kono
parents:
diff changeset
831 /* If variable's type was invalidly declared, just ignore it. */
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 type = TREE_TYPE (decl);
kono
parents:
diff changeset
834 if (TREE_CODE (type) == ERROR_MARK)
kono
parents:
diff changeset
835 return NULL_TREE;
kono
parents:
diff changeset
836
kono
parents:
diff changeset
837 if (MAYBE_CLASS_TYPE_P (type))
kono
parents:
diff changeset
838 {
kono
parents:
diff changeset
839 if (TREE_CODE (init) == TREE_LIST)
kono
parents:
diff changeset
840 {
kono
parents:
diff changeset
841 error ("constructor syntax used, but no constructor declared "
kono
parents:
diff changeset
842 "for type %qT", type);
kono
parents:
diff changeset
843 init = build_constructor_from_list (init_list_type_node, nreverse (init));
kono
parents:
diff changeset
844 }
kono
parents:
diff changeset
845 }
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 /* End of special C++ code. */
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 if (flags & LOOKUP_ALREADY_DIGESTED)
kono
parents:
diff changeset
850 value = init;
kono
parents:
diff changeset
851 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
852 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
853 if (TREE_STATIC (decl))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
854 flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
855 /* Digest the specified initializer into an expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
856 value = digest_init_flags (type, init, flags, tf_warning_or_error);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
857 }
111
kono
parents:
diff changeset
858
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
859 /* Look for braced array initializers for character arrays and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
860 recursively convert them into STRING_CSTs. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
861 value = braced_lists_to_strings (type, value);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
863 current_ref_temp_count = 0;
111
kono
parents:
diff changeset
864 value = extend_ref_init_temps (decl, value, cleanups);
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 /* In C++11 constant expression is a semantic, not syntactic, property.
kono
parents:
diff changeset
867 In C++98, make sure that what we thought was a constant expression at
kono
parents:
diff changeset
868 template definition time is still constant and otherwise perform this
kono
parents:
diff changeset
869 as optimization, e.g. to fold SIZEOF_EXPRs in the initializer. */
kono
parents:
diff changeset
870 if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl))
kono
parents:
diff changeset
871 {
kono
parents:
diff changeset
872 bool const_init;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 tree oldval = value;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 value = fold_non_dependent_expr (value);
111
kono
parents:
diff changeset
875 if (DECL_DECLARED_CONSTEXPR_P (decl)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876 || (DECL_IN_AGGR_P (decl)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
877 && DECL_INITIALIZED_IN_CLASS_P (decl)))
111
kono
parents:
diff changeset
878 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 /* Diagnose a non-constant initializer for constexpr variable or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880 non-inline in-class-initialized static data member. */
111
kono
parents:
diff changeset
881 if (!require_constant_expression (value))
kono
parents:
diff changeset
882 value = error_mark_node;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
883 else if (processing_template_decl)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 /* In a template we might not have done the necessary
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
885 transformations to make value actually constant,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
886 e.g. extend_ref_init_temps. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 value = maybe_constant_init (value, decl, true);
111
kono
parents:
diff changeset
888 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 value = cxx_constant_init (value, decl);
111
kono
parents:
diff changeset
890 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 value = maybe_constant_init (value, decl, true);
111
kono
parents:
diff changeset
893 if (TREE_CODE (value) == CONSTRUCTOR && cp_has_mutable_p (type))
kono
parents:
diff changeset
894 /* Poison this CONSTRUCTOR so it can't be copied to another
kono
parents:
diff changeset
895 constexpr variable. */
kono
parents:
diff changeset
896 CONSTRUCTOR_MUTABLE_POISON (value) = true;
kono
parents:
diff changeset
897 const_init = (reduced_constant_expression_p (value)
kono
parents:
diff changeset
898 || error_operand_p (value));
kono
parents:
diff changeset
899 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init;
kono
parents:
diff changeset
900 /* FIXME setting TREE_CONSTANT on refs breaks the back end. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 if (!TYPE_REF_P (type))
111
kono
parents:
diff changeset
902 TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 if (!const_init)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
904 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
905 /* [dcl.constinit]/2 "If a variable declared with the constinit
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
906 specifier has dynamic initialization, the program is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
907 ill-formed." */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
908 if (flags & LOOKUP_CONSTINIT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
909 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
910 error_at (location_of (decl),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
911 "%<constinit%> variable %qD does not have a constant "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
912 "initializer", decl);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
913 if (require_constant_expression (value))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
914 cxx_constant_init (value, decl);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
915 value = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
916 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
917 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
918 value = oldval;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
919 }
111
kono
parents:
diff changeset
920 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
921 /* Don't fold initializers of automatic variables in constexpr functions,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
922 that might fold away something that needs to be diagnosed at constexpr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
923 evaluation time. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
924 if (!current_function_decl
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
925 || !DECL_DECLARED_CONSTEXPR_P (current_function_decl)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
926 || TREE_STATIC (decl))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
927 value = cp_fully_fold_init (value);
111
kono
parents:
diff changeset
928
kono
parents:
diff changeset
929 /* Handle aggregate NSDMI in non-constant initializers, too. */
kono
parents:
diff changeset
930 value = replace_placeholders (value, decl);
kono
parents:
diff changeset
931
kono
parents:
diff changeset
932 /* If the initializer is not a constant, fill in DECL_INITIAL with
kono
parents:
diff changeset
933 the bits that are constant, and then return an expression that
kono
parents:
diff changeset
934 will perform the dynamic initialization. */
kono
parents:
diff changeset
935 if (value != error_mark_node
kono
parents:
diff changeset
936 && (TREE_SIDE_EFFECTS (value)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 || vla_type_p (type)
111
kono
parents:
diff changeset
938 || ! reduced_constant_expression_p (value)))
kono
parents:
diff changeset
939 return split_nonconstant_init (decl, value);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
940
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
941 /* DECL may change value; purge caches. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
942 clear_cv_and_fold_caches (TREE_STATIC (decl));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
943
111
kono
parents:
diff changeset
944 /* If the value is a constant, just put it in DECL_INITIAL. If DECL
kono
parents:
diff changeset
945 is an automatic variable, the middle end will turn this into a
kono
parents:
diff changeset
946 dynamic initialization later. */
kono
parents:
diff changeset
947 DECL_INITIAL (decl) = value;
kono
parents:
diff changeset
948 return NULL_TREE;
kono
parents:
diff changeset
949 }
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 /* Give diagnostic about narrowing conversions within { }, or as part of
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 a converted constant expression. If CONST_ONLY, only check
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 constants. */
111
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
957 check_narrowing (tree type, tree init, tsubst_flags_t complain,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
958 bool const_only/*= false*/)
111
kono
parents:
diff changeset
959 {
kono
parents:
diff changeset
960 tree ftype = unlowered_expr_type (init);
kono
parents:
diff changeset
961 bool ok = true;
kono
parents:
diff changeset
962 REAL_VALUE_TYPE d;
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 if (((!warn_narrowing || !(complain & tf_warning))
kono
parents:
diff changeset
965 && cxx_dialect == cxx98)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 || !ARITHMETIC_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
967 /* Don't emit bogus warnings with e.g. value-dependent trees. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 || instantiation_dependent_expression_p (init))
111
kono
parents:
diff changeset
969 return ok;
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 if (BRACE_ENCLOSED_INITIALIZER_P (init)
kono
parents:
diff changeset
972 && TREE_CODE (type) == COMPLEX_TYPE)
kono
parents:
diff changeset
973 {
kono
parents:
diff changeset
974 tree elttype = TREE_TYPE (type);
kono
parents:
diff changeset
975 if (CONSTRUCTOR_NELTS (init) > 0)
kono
parents:
diff changeset
976 ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value,
kono
parents:
diff changeset
977 complain);
kono
parents:
diff changeset
978 if (CONSTRUCTOR_NELTS (init) > 1)
kono
parents:
diff changeset
979 ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value,
kono
parents:
diff changeset
980 complain);
kono
parents:
diff changeset
981 return ok;
kono
parents:
diff changeset
982 }
kono
parents:
diff changeset
983
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 init = maybe_constant_value (init);
111
kono
parents:
diff changeset
985
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 /* If we were asked to only check constants, return early. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 if (const_only && !TREE_CONSTANT (init))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 return ok;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
990 if (CP_INTEGRAL_TYPE_P (type)
111
kono
parents:
diff changeset
991 && TREE_CODE (ftype) == REAL_TYPE)
kono
parents:
diff changeset
992 ok = false;
kono
parents:
diff changeset
993 else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
kono
parents:
diff changeset
994 && CP_INTEGRAL_TYPE_P (type))
kono
parents:
diff changeset
995 {
kono
parents:
diff changeset
996 if (TREE_CODE (ftype) == ENUMERAL_TYPE)
kono
parents:
diff changeset
997 /* Check for narrowing based on the values of the enumeration. */
kono
parents:
diff changeset
998 ftype = ENUM_UNDERLYING_TYPE (ftype);
kono
parents:
diff changeset
999 if ((tree_int_cst_lt (TYPE_MAX_VALUE (type),
kono
parents:
diff changeset
1000 TYPE_MAX_VALUE (ftype))
kono
parents:
diff changeset
1001 || tree_int_cst_lt (TYPE_MIN_VALUE (ftype),
kono
parents:
diff changeset
1002 TYPE_MIN_VALUE (type)))
kono
parents:
diff changeset
1003 && (TREE_CODE (init) != INTEGER_CST
kono
parents:
diff changeset
1004 || !int_fits_type_p (init, type)))
kono
parents:
diff changeset
1005 ok = false;
kono
parents:
diff changeset
1006 }
kono
parents:
diff changeset
1007 else if (TREE_CODE (ftype) == REAL_TYPE
kono
parents:
diff changeset
1008 && TREE_CODE (type) == REAL_TYPE)
kono
parents:
diff changeset
1009 {
kono
parents:
diff changeset
1010 if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))
kono
parents:
diff changeset
1011 {
kono
parents:
diff changeset
1012 if (TREE_CODE (init) == REAL_CST)
kono
parents:
diff changeset
1013 {
kono
parents:
diff changeset
1014 /* Issue 703: Loss of precision is OK as long as the value is
kono
parents:
diff changeset
1015 within the representable range of the new type. */
kono
parents:
diff changeset
1016 REAL_VALUE_TYPE r;
kono
parents:
diff changeset
1017 d = TREE_REAL_CST (init);
kono
parents:
diff changeset
1018 real_convert (&r, TYPE_MODE (type), &d);
kono
parents:
diff changeset
1019 if (real_isinf (&r))
kono
parents:
diff changeset
1020 ok = false;
kono
parents:
diff changeset
1021 }
kono
parents:
diff changeset
1022 else
kono
parents:
diff changeset
1023 ok = false;
kono
parents:
diff changeset
1024 }
kono
parents:
diff changeset
1025 }
kono
parents:
diff changeset
1026 else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
kono
parents:
diff changeset
1027 && TREE_CODE (type) == REAL_TYPE)
kono
parents:
diff changeset
1028 {
kono
parents:
diff changeset
1029 ok = false;
kono
parents:
diff changeset
1030 if (TREE_CODE (init) == INTEGER_CST)
kono
parents:
diff changeset
1031 {
kono
parents:
diff changeset
1032 d = real_value_from_int_cst (0, init);
kono
parents:
diff changeset
1033 if (exact_real_truncate (TYPE_MODE (type), &d))
kono
parents:
diff changeset
1034 ok = true;
kono
parents:
diff changeset
1035 }
kono
parents:
diff changeset
1036 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1037 else if (TREE_CODE (type) == BOOLEAN_TYPE
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1038 && (TYPE_PTR_P (ftype) || TYPE_PTRMEM_P (ftype)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1039 /* This hasn't actually made it into C++20 yet, but let's add it now to get
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1040 an idea of the impact. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1041 ok = (cxx_dialect < cxx2a);
111
kono
parents:
diff changeset
1042
kono
parents:
diff changeset
1043 bool almost_ok = ok;
kono
parents:
diff changeset
1044 if (!ok && !CONSTANT_CLASS_P (init) && (complain & tf_warning_or_error))
kono
parents:
diff changeset
1045 {
kono
parents:
diff changeset
1046 tree folded = cp_fully_fold (init);
kono
parents:
diff changeset
1047 if (TREE_CONSTANT (folded) && check_narrowing (type, folded, tf_none))
kono
parents:
diff changeset
1048 almost_ok = true;
kono
parents:
diff changeset
1049 }
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 if (!ok)
kono
parents:
diff changeset
1052 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1053 location_t loc = cp_expr_loc_or_input_loc (init);
111
kono
parents:
diff changeset
1054 if (cxx_dialect == cxx98)
kono
parents:
diff changeset
1055 {
kono
parents:
diff changeset
1056 if (complain & tf_warning)
kono
parents:
diff changeset
1057 warning_at (loc, OPT_Wnarrowing, "narrowing conversion of %qE "
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1058 "from %qH to %qI is ill-formed in C++11",
111
kono
parents:
diff changeset
1059 init, ftype, type);
kono
parents:
diff changeset
1060 ok = true;
kono
parents:
diff changeset
1061 }
kono
parents:
diff changeset
1062 else if (!CONSTANT_CLASS_P (init))
kono
parents:
diff changeset
1063 {
kono
parents:
diff changeset
1064 if (complain & tf_warning_or_error)
kono
parents:
diff changeset
1065 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1066 auto_diagnostic_group d;
111
kono
parents:
diff changeset
1067 if ((!almost_ok || pedantic)
kono
parents:
diff changeset
1068 && pedwarn (loc, OPT_Wnarrowing,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1069 "narrowing conversion of %qE from %qH to %qI",
111
kono
parents:
diff changeset
1070 init, ftype, type)
kono
parents:
diff changeset
1071 && almost_ok)
kono
parents:
diff changeset
1072 inform (loc, " the expression has a constant value but is not "
kono
parents:
diff changeset
1073 "a C++ constant-expression");
kono
parents:
diff changeset
1074 ok = true;
kono
parents:
diff changeset
1075 }
kono
parents:
diff changeset
1076 }
kono
parents:
diff changeset
1077 else if (complain & tf_error)
kono
parents:
diff changeset
1078 {
kono
parents:
diff changeset
1079 int savederrorcount = errorcount;
kono
parents:
diff changeset
1080 global_dc->pedantic_errors = 1;
kono
parents:
diff changeset
1081 pedwarn (loc, OPT_Wnarrowing,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1082 "narrowing conversion of %qE from %qH to %qI",
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1083 init, ftype, type);
111
kono
parents:
diff changeset
1084 if (errorcount == savederrorcount)
kono
parents:
diff changeset
1085 ok = true;
kono
parents:
diff changeset
1086 global_dc->pedantic_errors = flag_pedantic_errors;
kono
parents:
diff changeset
1087 }
kono
parents:
diff changeset
1088 }
kono
parents:
diff changeset
1089
kono
parents:
diff changeset
1090 return ok;
kono
parents:
diff changeset
1091 }
kono
parents:
diff changeset
1092
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1093 /* True iff TYPE is a C++2a "ordinary" character type. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1094
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1095 bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1096 ordinary_char_type_p (tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1097 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1098 type = TYPE_MAIN_VARIANT (type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1099 return (type == char_type_node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1100 || type == signed_char_type_node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1101 || type == unsigned_char_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1102 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1103
111
kono
parents:
diff changeset
1104 /* Process the initializer INIT for a variable of type TYPE, emitting
kono
parents:
diff changeset
1105 diagnostics for invalid initializers and converting the initializer as
kono
parents:
diff changeset
1106 appropriate.
kono
parents:
diff changeset
1107
kono
parents:
diff changeset
1108 For aggregate types, it assumes that reshape_init has already run, thus the
kono
parents:
diff changeset
1109 initializer will have the right shape (brace elision has been undone).
kono
parents:
diff changeset
1110
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 NESTED is non-zero iff we are being called for an element of a CONSTRUCTOR,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1112 2 iff the element of a CONSTRUCTOR is inside another CONSTRUCTOR. */
111
kono
parents:
diff changeset
1113
kono
parents:
diff changeset
1114 static tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1115 digest_init_r (tree type, tree init, int nested, int flags,
111
kono
parents:
diff changeset
1116 tsubst_flags_t complain)
kono
parents:
diff changeset
1117 {
kono
parents:
diff changeset
1118 enum tree_code code = TREE_CODE (type);
kono
parents:
diff changeset
1119
kono
parents:
diff changeset
1120 if (error_operand_p (init))
kono
parents:
diff changeset
1121 return error_mark_node;
kono
parents:
diff changeset
1122
kono
parents:
diff changeset
1123 gcc_assert (init);
kono
parents:
diff changeset
1124
kono
parents:
diff changeset
1125 /* We must strip the outermost array type when completing the type,
kono
parents:
diff changeset
1126 because the its bounds might be incomplete at the moment. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1127 if (!complete_type_or_maybe_complain (code == ARRAY_TYPE
111
kono
parents:
diff changeset
1128 ? TREE_TYPE (type) : type, NULL_TREE,
kono
parents:
diff changeset
1129 complain))
kono
parents:
diff changeset
1130 return error_mark_node;
kono
parents:
diff changeset
1131
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 location_t loc = cp_expr_loc_or_input_loc (init);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1133
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1134 tree stripped_init = init;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1135
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1136 if (BRACE_ENCLOSED_INITIALIZER_P (init)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1137 && CONSTRUCTOR_IS_PAREN_INIT (init))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1138 flags |= LOOKUP_AGGREGATE_PAREN_INIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1139
111
kono
parents:
diff changeset
1140 /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
kono
parents:
diff changeset
1141 (g++.old-deja/g++.law/casts2.C). */
kono
parents:
diff changeset
1142 if (TREE_CODE (init) == NON_LVALUE_EXPR)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1143 stripped_init = TREE_OPERAND (init, 0);
111
kono
parents:
diff changeset
1144
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1145 stripped_init = tree_strip_any_location_wrapper (stripped_init);
111
kono
parents:
diff changeset
1146
kono
parents:
diff changeset
1147 /* Initialization of an array of chars from a string constant. The initializer
kono
parents:
diff changeset
1148 can be optionally enclosed in braces, but reshape_init has already removed
kono
parents:
diff changeset
1149 them if they were present. */
kono
parents:
diff changeset
1150 if (code == ARRAY_TYPE)
kono
parents:
diff changeset
1151 {
kono
parents:
diff changeset
1152 if (nested && !TYPE_DOMAIN (type))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1153 /* C++ flexible array members have a null domain. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1154 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1155 if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1156 pedwarn (loc, OPT_Wpedantic,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1157 "initialization of a flexible array member");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1158 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1159 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1160 if (complain & tf_error)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 error_at (loc, "non-static initialization of"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1162 " a flexible array member");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1163 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1164 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1165 }
111
kono
parents:
diff changeset
1166
kono
parents:
diff changeset
1167 tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
kono
parents:
diff changeset
1168 if (char_type_p (typ1)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1169 && TREE_CODE (stripped_init) == STRING_CST)
111
kono
parents:
diff changeset
1170 {
kono
parents:
diff changeset
1171 tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1172 bool incompat_string_cst = false;
111
kono
parents:
diff changeset
1173
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1174 if (typ1 != char_type)
111
kono
parents:
diff changeset
1175 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 /* The array element type does not match the initializing string
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 literal element type; this is only allowed when both types are
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1178 ordinary character type. There are no string literals of
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 signed or unsigned char type in the language, but we can get
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 them internally from converting braced-init-lists to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 STRING_CST. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1182 if (ordinary_char_type_p (typ1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1183 && ordinary_char_type_p (char_type))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 /* OK */;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1186 incompat_string_cst = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1187 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 if (incompat_string_cst)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 if (complain & tf_error)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 error_at (loc, "cannot initialize array of %qT from "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 "a string literal with type array of %qT",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 typ1, char_type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195 return error_mark_node;
111
kono
parents:
diff changeset
1196 }
kono
parents:
diff changeset
1197
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1198 if (nested == 2 && !TYPE_DOMAIN (type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1199 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1200 if (complain & tf_error)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1201 error_at (loc, "initialization of flexible array member "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1202 "in a nested context");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1203 return error_mark_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1204 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1205
111
kono
parents:
diff changeset
1206 if (type != TREE_TYPE (init)
kono
parents:
diff changeset
1207 && !variably_modified_type_p (type, NULL_TREE))
kono
parents:
diff changeset
1208 {
kono
parents:
diff changeset
1209 init = copy_node (init);
kono
parents:
diff changeset
1210 TREE_TYPE (init) = type;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1211 /* If we have a location wrapper, then also copy the wrapped
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212 node, and update the copy's type. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1213 if (location_wrapper_p (init))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1215 stripped_init = copy_node (stripped_init);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1216 TREE_OPERAND (init, 0) = stripped_init;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1217 TREE_TYPE (stripped_init) = type;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1218 }
111
kono
parents:
diff changeset
1219 }
kono
parents:
diff changeset
1220 if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type)))
kono
parents:
diff changeset
1221 {
kono
parents:
diff changeset
1222 /* Not a flexible array member. */
kono
parents:
diff changeset
1223 int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
kono
parents:
diff changeset
1224 size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
kono
parents:
diff changeset
1225 /* In C it is ok to subtract 1 from the length of the string
kono
parents:
diff changeset
1226 because it's ok to ignore the terminating null char that is
kono
parents:
diff changeset
1227 counted in the length of the constant, but in C++ this would
kono
parents:
diff changeset
1228 be invalid. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1229 if (size < TREE_STRING_LENGTH (stripped_init))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1230 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1231 permerror (loc, "initializer-string for %qT is too long",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1232 type);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1233
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1234 init = build_string (size,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1235 TREE_STRING_POINTER (stripped_init));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1236 TREE_TYPE (init) = type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1237 }
111
kono
parents:
diff changeset
1238 }
kono
parents:
diff changeset
1239 return init;
kono
parents:
diff changeset
1240 }
kono
parents:
diff changeset
1241 }
kono
parents:
diff changeset
1242
kono
parents:
diff changeset
1243 /* Handle scalar types (including conversions) and references. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1244 if ((code != COMPLEX_TYPE || BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
111
kono
parents:
diff changeset
1245 && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
kono
parents:
diff changeset
1246 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1247 /* Narrowing is OK when initializing an aggregate from
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1248 a parenthesized list. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1249 if (nested && !(flags & LOOKUP_AGGREGATE_PAREN_INIT))
111
kono
parents:
diff changeset
1250 flags |= LOOKUP_NO_NARROWING;
kono
parents:
diff changeset
1251 init = convert_for_initialization (0, type, init, flags,
kono
parents:
diff changeset
1252 ICR_INIT, NULL_TREE, 0,
kono
parents:
diff changeset
1253 complain);
kono
parents:
diff changeset
1254
kono
parents:
diff changeset
1255 return init;
kono
parents:
diff changeset
1256 }
kono
parents:
diff changeset
1257
kono
parents:
diff changeset
1258 /* Come here only for aggregates: records, arrays, unions, complex numbers
kono
parents:
diff changeset
1259 and vectors. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1260 gcc_assert (code == ARRAY_TYPE
111
kono
parents:
diff changeset
1261 || VECTOR_TYPE_P (type)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1262 || code == RECORD_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1263 || code == UNION_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1264 || code == COMPLEX_TYPE);
111
kono
parents:
diff changeset
1265
kono
parents:
diff changeset
1266 /* "If T is a class type and the initializer list has a single
kono
parents:
diff changeset
1267 element of type cv U, where U is T or a class derived from T,
kono
parents:
diff changeset
1268 the object is initialized from that element." */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1269 if (cxx_dialect >= cxx11
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1270 && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1271 && CONSTRUCTOR_NELTS (stripped_init) == 1
111
kono
parents:
diff changeset
1272 && ((CLASS_TYPE_P (type) && !CLASSTYPE_NON_AGGREGATE (type))
kono
parents:
diff changeset
1273 || VECTOR_TYPE_P (type)))
kono
parents:
diff changeset
1274 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1275 tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value;
111
kono
parents:
diff changeset
1276 if (reference_related_p (type, TREE_TYPE (elt)))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1277 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1278 /* In C++17, aggregates can have bases, thus participate in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1279 aggregate initialization. In the following case:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1280
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1281 struct B { int c; };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1282 struct D : B { };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1283 D d{{D{{42}}}};
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1284
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1285 there's an extra set of braces, so the D temporary initializes
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1286 the first element of d, which is the B base subobject. The base
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1287 of type B is copy-initialized from the D temporary, causing
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1288 object slicing. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1289 tree field = next_initializable_field (TYPE_FIELDS (type));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1290 if (field && DECL_FIELD_IS_BASE (field))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1291 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1292 if (warning_at (loc, 0, "initializing a base class of type %qT "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1293 "results in object slicing", TREE_TYPE (field)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1294 inform (loc, "remove %<{ }%> around initializer");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1295 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1296 else if (flag_checking)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1297 /* We should have fixed this in reshape_init. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1298 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1299 }
111
kono
parents:
diff changeset
1300 }
kono
parents:
diff changeset
1301
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1302 if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
111
kono
parents:
diff changeset
1303 && !TYPE_NON_AGGREGATE_CLASS (type))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1304 return process_init_constructor (type, stripped_init, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1305 complain);
111
kono
parents:
diff changeset
1306 else
kono
parents:
diff changeset
1307 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1308 if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
111
kono
parents:
diff changeset
1309 {
kono
parents:
diff changeset
1310 if (complain & tf_error)
kono
parents:
diff changeset
1311 error_at (loc, "cannot initialize aggregate of type %qT with "
kono
parents:
diff changeset
1312 "a compound literal", type);
kono
parents:
diff changeset
1313
kono
parents:
diff changeset
1314 return error_mark_node;
kono
parents:
diff changeset
1315 }
kono
parents:
diff changeset
1316
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1317 if (code == ARRAY_TYPE
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1318 && !BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
111
kono
parents:
diff changeset
1319 {
kono
parents:
diff changeset
1320 /* Allow the result of build_array_copy and of
kono
parents:
diff changeset
1321 build_value_init_noctor. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1322 if ((TREE_CODE (stripped_init) == VEC_INIT_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1323 || TREE_CODE (stripped_init) == CONSTRUCTOR)
111
kono
parents:
diff changeset
1324 && (same_type_ignoring_top_level_qualifiers_p
kono
parents:
diff changeset
1325 (type, TREE_TYPE (init))))
kono
parents:
diff changeset
1326 return init;
kono
parents:
diff changeset
1327
kono
parents:
diff changeset
1328 if (complain & tf_error)
kono
parents:
diff changeset
1329 error_at (loc, "array must be initialized with a brace-enclosed"
kono
parents:
diff changeset
1330 " initializer");
kono
parents:
diff changeset
1331 return error_mark_node;
kono
parents:
diff changeset
1332 }
kono
parents:
diff changeset
1333
kono
parents:
diff changeset
1334 return convert_for_initialization (NULL_TREE, type, init,
kono
parents:
diff changeset
1335 flags,
kono
parents:
diff changeset
1336 ICR_INIT, NULL_TREE, 0,
kono
parents:
diff changeset
1337 complain);
kono
parents:
diff changeset
1338 }
kono
parents:
diff changeset
1339 }
kono
parents:
diff changeset
1340
kono
parents:
diff changeset
1341 tree
kono
parents:
diff changeset
1342 digest_init (tree type, tree init, tsubst_flags_t complain)
kono
parents:
diff changeset
1343 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1344 return digest_init_r (type, init, 0, LOOKUP_IMPLICIT, complain);
111
kono
parents:
diff changeset
1345 }
kono
parents:
diff changeset
1346
kono
parents:
diff changeset
1347 tree
kono
parents:
diff changeset
1348 digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain)
kono
parents:
diff changeset
1349 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1350 return digest_init_r (type, init, 0, flags, complain);
111
kono
parents:
diff changeset
1351 }
kono
parents:
diff changeset
1352
kono
parents:
diff changeset
1353 /* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */
kono
parents:
diff changeset
1354 tree
kono
parents:
diff changeset
1355 digest_nsdmi_init (tree decl, tree init, tsubst_flags_t complain)
kono
parents:
diff changeset
1356 {
kono
parents:
diff changeset
1357 gcc_assert (TREE_CODE (decl) == FIELD_DECL);
kono
parents:
diff changeset
1358
kono
parents:
diff changeset
1359 tree type = TREE_TYPE (decl);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1360 if (DECL_BIT_FIELD_TYPE (decl))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1361 type = DECL_BIT_FIELD_TYPE (decl);
111
kono
parents:
diff changeset
1362 int flags = LOOKUP_IMPLICIT;
kono
parents:
diff changeset
1363 if (DIRECT_LIST_INIT_P (init))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1364 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1365 flags = LOOKUP_NORMAL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1366 complain |= tf_no_cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1367 }
111
kono
parents:
diff changeset
1368 if (BRACE_ENCLOSED_INITIALIZER_P (init)
kono
parents:
diff changeset
1369 && CP_AGGREGATE_TYPE_P (type))
kono
parents:
diff changeset
1370 init = reshape_init (type, init, complain);
kono
parents:
diff changeset
1371 init = digest_init_flags (type, init, flags, complain);
kono
parents:
diff changeset
1372 return init;
kono
parents:
diff changeset
1373 }
kono
parents:
diff changeset
1374
kono
parents:
diff changeset
1375 /* Set of flags used within process_init_constructor to describe the
kono
parents:
diff changeset
1376 initializers. */
kono
parents:
diff changeset
1377 #define PICFLAG_ERRONEOUS 1
kono
parents:
diff changeset
1378 #define PICFLAG_NOT_ALL_CONSTANT 2
kono
parents:
diff changeset
1379 #define PICFLAG_NOT_ALL_SIMPLE 4
kono
parents:
diff changeset
1380 #define PICFLAG_SIDE_EFFECTS 8
kono
parents:
diff changeset
1381
kono
parents:
diff changeset
1382 /* Given an initializer INIT, return the flag (PICFLAG_*) which better
kono
parents:
diff changeset
1383 describe it. */
kono
parents:
diff changeset
1384
kono
parents:
diff changeset
1385 static int
kono
parents:
diff changeset
1386 picflag_from_initializer (tree init)
kono
parents:
diff changeset
1387 {
kono
parents:
diff changeset
1388 if (init == error_mark_node)
kono
parents:
diff changeset
1389 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1390 else if (!TREE_CONSTANT (init))
kono
parents:
diff changeset
1391 {
kono
parents:
diff changeset
1392 if (TREE_SIDE_EFFECTS (init))
kono
parents:
diff changeset
1393 return PICFLAG_SIDE_EFFECTS;
kono
parents:
diff changeset
1394 else
kono
parents:
diff changeset
1395 return PICFLAG_NOT_ALL_CONSTANT;
kono
parents:
diff changeset
1396 }
kono
parents:
diff changeset
1397 else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
kono
parents:
diff changeset
1398 return PICFLAG_NOT_ALL_SIMPLE;
kono
parents:
diff changeset
1399 return 0;
kono
parents:
diff changeset
1400 }
kono
parents:
diff changeset
1401
kono
parents:
diff changeset
1402 /* Adjust INIT for going into a CONSTRUCTOR. */
kono
parents:
diff changeset
1403
kono
parents:
diff changeset
1404 static tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1405 massage_init_elt (tree type, tree init, int nested, int flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1406 tsubst_flags_t complain)
111
kono
parents:
diff changeset
1407 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1408 int new_flags = LOOKUP_IMPLICIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1409 if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1410 new_flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1411 if (flags & LOOKUP_AGGREGATE_PAREN_INIT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1412 new_flags |= LOOKUP_AGGREGATE_PAREN_INIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1413 init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain);
111
kono
parents:
diff changeset
1414 /* Strip a simple TARGET_EXPR when we know this is an initializer. */
kono
parents:
diff changeset
1415 if (SIMPLE_TARGET_EXPR_P (init))
kono
parents:
diff changeset
1416 init = TARGET_EXPR_INITIAL (init);
kono
parents:
diff changeset
1417 /* When we defer constant folding within a statement, we may want to
kono
parents:
diff changeset
1418 defer this folding as well. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1419 tree t = fold_non_dependent_init (init, complain);
111
kono
parents:
diff changeset
1420 if (TREE_CONSTANT (t))
kono
parents:
diff changeset
1421 init = t;
kono
parents:
diff changeset
1422 return init;
kono
parents:
diff changeset
1423 }
kono
parents:
diff changeset
1424
kono
parents:
diff changeset
1425 /* Subroutine of process_init_constructor, which will process an initializer
kono
parents:
diff changeset
1426 INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
kono
parents:
diff changeset
1427 which describe the initializers. */
kono
parents:
diff changeset
1428
kono
parents:
diff changeset
1429 static int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1430 process_init_constructor_array (tree type, tree init, int nested, int flags,
111
kono
parents:
diff changeset
1431 tsubst_flags_t complain)
kono
parents:
diff changeset
1432 {
kono
parents:
diff changeset
1433 unsigned HOST_WIDE_INT i, len = 0;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1434 int picflags = 0;
111
kono
parents:
diff changeset
1435 bool unbounded = false;
kono
parents:
diff changeset
1436 constructor_elt *ce;
kono
parents:
diff changeset
1437 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 gcc_assert (TREE_CODE (type) == ARRAY_TYPE
kono
parents:
diff changeset
1440 || VECTOR_TYPE_P (type));
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 if (TREE_CODE (type) == ARRAY_TYPE)
kono
parents:
diff changeset
1443 {
kono
parents:
diff changeset
1444 /* C++ flexible array members have a null domain. */
kono
parents:
diff changeset
1445 tree domain = TYPE_DOMAIN (type);
kono
parents:
diff changeset
1446 if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
kono
parents:
diff changeset
1447 len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
kono
parents:
diff changeset
1448 - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
kono
parents:
diff changeset
1449 TYPE_PRECISION (TREE_TYPE (domain)),
kono
parents:
diff changeset
1450 TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
kono
parents:
diff changeset
1451 else
kono
parents:
diff changeset
1452 unbounded = true; /* Take as many as there are. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1453
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1454 if (nested == 2 && !domain && !vec_safe_is_empty (v))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1455 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1456 if (complain & tf_error)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1457 error_at (cp_expr_loc_or_input_loc (init),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1458 "initialization of flexible array member "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1459 "in a nested context");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1460 return PICFLAG_ERRONEOUS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1461 }
111
kono
parents:
diff changeset
1462 }
kono
parents:
diff changeset
1463 else
kono
parents:
diff changeset
1464 /* Vectors are like simple fixed-size arrays. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1465 unbounded = !TYPE_VECTOR_SUBPARTS (type).is_constant (&len);
111
kono
parents:
diff changeset
1466
kono
parents:
diff changeset
1467 /* There must not be more initializers than needed. */
kono
parents:
diff changeset
1468 if (!unbounded && vec_safe_length (v) > len)
kono
parents:
diff changeset
1469 {
kono
parents:
diff changeset
1470 if (complain & tf_error)
kono
parents:
diff changeset
1471 error ("too many initializers for %qT", type);
kono
parents:
diff changeset
1472 else
kono
parents:
diff changeset
1473 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1474 }
kono
parents:
diff changeset
1475
kono
parents:
diff changeset
1476 FOR_EACH_VEC_SAFE_ELT (v, i, ce)
kono
parents:
diff changeset
1477 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 if (!ce->index)
111
kono
parents:
diff changeset
1479 ce->index = size_int (i);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1480 else if (!check_array_designated_initializer (ce, i))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1481 ce->index = error_mark_node;
111
kono
parents:
diff changeset
1482 gcc_assert (ce->value);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1483 ce->value
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1484 = massage_init_elt (TREE_TYPE (type), ce->value, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1485 complain);
111
kono
parents:
diff changeset
1486
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1487 gcc_checking_assert
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1488 (ce->value == error_mark_node
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1489 || (same_type_ignoring_top_level_qualifiers_p
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1490 (strip_array_types (TREE_TYPE (type)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1491 strip_array_types (TREE_TYPE (ce->value)))));
111
kono
parents:
diff changeset
1492
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1493 picflags |= picflag_from_initializer (ce->value);
111
kono
parents:
diff changeset
1494 }
kono
parents:
diff changeset
1495
kono
parents:
diff changeset
1496 /* No more initializers. If the array is unbounded, we are done. Otherwise,
kono
parents:
diff changeset
1497 we must add initializers ourselves. */
kono
parents:
diff changeset
1498 if (!unbounded)
kono
parents:
diff changeset
1499 for (; i < len; ++i)
kono
parents:
diff changeset
1500 {
kono
parents:
diff changeset
1501 tree next;
kono
parents:
diff changeset
1502
kono
parents:
diff changeset
1503 if (type_build_ctor_call (TREE_TYPE (type)))
kono
parents:
diff changeset
1504 {
kono
parents:
diff changeset
1505 /* If this type needs constructors run for default-initialization,
kono
parents:
diff changeset
1506 we can't rely on the back end to do it for us, so make the
kono
parents:
diff changeset
1507 initialization explicit by list-initializing from T{}. */
kono
parents:
diff changeset
1508 next = build_constructor (init_list_type_node, NULL);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1509 next = massage_init_elt (TREE_TYPE (type), next, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1510 complain);
111
kono
parents:
diff changeset
1511 if (initializer_zerop (next))
kono
parents:
diff changeset
1512 /* The default zero-initialization is fine for us; don't
kono
parents:
diff changeset
1513 add anything to the CONSTRUCTOR. */
kono
parents:
diff changeset
1514 next = NULL_TREE;
kono
parents:
diff changeset
1515 }
kono
parents:
diff changeset
1516 else if (!zero_init_p (TREE_TYPE (type)))
kono
parents:
diff changeset
1517 next = build_zero_init (TREE_TYPE (type),
kono
parents:
diff changeset
1518 /*nelts=*/NULL_TREE,
kono
parents:
diff changeset
1519 /*static_storage_p=*/false);
kono
parents:
diff changeset
1520 else
kono
parents:
diff changeset
1521 /* The default zero-initialization is fine for us; don't
kono
parents:
diff changeset
1522 add anything to the CONSTRUCTOR. */
kono
parents:
diff changeset
1523 next = NULL_TREE;
kono
parents:
diff changeset
1524
kono
parents:
diff changeset
1525 if (next)
kono
parents:
diff changeset
1526 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1527 picflags |= picflag_from_initializer (next);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1528 if (len > i+1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1529 && (initializer_constant_valid_p (next, TREE_TYPE (next))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1530 == null_pointer_node))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1531 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 tree range = build2 (RANGE_EXPR, size_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1533 build_int_cst (size_type_node, i),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534 build_int_cst (size_type_node, len - 1));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1535 CONSTRUCTOR_APPEND_ELT (v, range, next);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1536 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1537 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1538 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1539 CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
111
kono
parents:
diff changeset
1540 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1541 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1542 /* Don't bother checking all the other elements. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1543 break;
111
kono
parents:
diff changeset
1544 }
kono
parents:
diff changeset
1545
kono
parents:
diff changeset
1546 CONSTRUCTOR_ELTS (init) = v;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1547 return picflags;
111
kono
parents:
diff changeset
1548 }
kono
parents:
diff changeset
1549
kono
parents:
diff changeset
1550 /* Subroutine of process_init_constructor, which will process an initializer
kono
parents:
diff changeset
1551 INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
kono
parents:
diff changeset
1552 the initializers. */
kono
parents:
diff changeset
1553
kono
parents:
diff changeset
1554 static int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1555 process_init_constructor_record (tree type, tree init, int nested, int flags,
111
kono
parents:
diff changeset
1556 tsubst_flags_t complain)
kono
parents:
diff changeset
1557 {
kono
parents:
diff changeset
1558 vec<constructor_elt, va_gc> *v = NULL;
kono
parents:
diff changeset
1559 tree field;
kono
parents:
diff changeset
1560 int skipped = 0;
kono
parents:
diff changeset
1561
kono
parents:
diff changeset
1562 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
kono
parents:
diff changeset
1563 gcc_assert (!CLASSTYPE_VBASECLASSES (type));
kono
parents:
diff changeset
1564 gcc_assert (!TYPE_BINFO (type)
kono
parents:
diff changeset
1565 || cxx_dialect >= cxx17
kono
parents:
diff changeset
1566 || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
kono
parents:
diff changeset
1567 gcc_assert (!TYPE_POLYMORPHIC_P (type));
kono
parents:
diff changeset
1568
kono
parents:
diff changeset
1569 restart:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1570 int picflags = 0;
111
kono
parents:
diff changeset
1571 unsigned HOST_WIDE_INT idx = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1572 int designator_skip = -1;
111
kono
parents:
diff changeset
1573 /* Generally, we will always have an index for each initializer (which is
kono
parents:
diff changeset
1574 a FIELD_DECL, put by reshape_init), but compound literals don't go trough
kono
parents:
diff changeset
1575 reshape_init. So we need to handle both cases. */
kono
parents:
diff changeset
1576 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
kono
parents:
diff changeset
1577 {
kono
parents:
diff changeset
1578 tree next;
kono
parents:
diff changeset
1579 tree type;
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 if (TREE_CODE (field) != FIELD_DECL
kono
parents:
diff changeset
1582 || (DECL_ARTIFICIAL (field)
kono
parents:
diff changeset
1583 && !(cxx_dialect >= cxx17 && DECL_FIELD_IS_BASE (field))))
kono
parents:
diff changeset
1584 continue;
kono
parents:
diff changeset
1585
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1586 if (DECL_UNNAMED_BIT_FIELD (field))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1587 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1588
111
kono
parents:
diff changeset
1589 /* If this is a bitfield, first convert to the declared type. */
kono
parents:
diff changeset
1590 type = TREE_TYPE (field);
kono
parents:
diff changeset
1591 if (DECL_BIT_FIELD_TYPE (field))
kono
parents:
diff changeset
1592 type = DECL_BIT_FIELD_TYPE (field);
kono
parents:
diff changeset
1593 if (type == error_mark_node)
kono
parents:
diff changeset
1594 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1595
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1596 next = NULL_TREE;
111
kono
parents:
diff changeset
1597 if (idx < CONSTRUCTOR_NELTS (init))
kono
parents:
diff changeset
1598 {
kono
parents:
diff changeset
1599 constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
kono
parents:
diff changeset
1600 if (ce->index)
kono
parents:
diff changeset
1601 {
kono
parents:
diff changeset
1602 /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
kono
parents:
diff changeset
1603 latter case can happen in templates where lookup has to be
kono
parents:
diff changeset
1604 deferred. */
kono
parents:
diff changeset
1605 gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
kono
parents:
diff changeset
1606 || identifier_p (ce->index));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1607 if (ce->index == field || ce->index == DECL_NAME (field))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1608 next = ce->value;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1609 else if (ANON_AGGR_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1610 && search_anon_aggr (type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1611 TREE_CODE (ce->index) == FIELD_DECL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1612 ? DECL_NAME (ce->index)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1613 : ce->index))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1614 /* If the element is an anonymous union object and the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1615 initializer list is a designated-initializer-list, the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1616 anonymous union object is initialized by the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1617 designated-initializer-list { D }, where D is the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1618 designated-initializer-clause naming a member of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1619 anonymous union object. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1620 next = build_constructor_single (init_list_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1621 ce->index, ce->value);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1622 else
111
kono
parents:
diff changeset
1623 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1624 ce = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1625 if (designator_skip == -1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1626 designator_skip = 1;
111
kono
parents:
diff changeset
1627 }
kono
parents:
diff changeset
1628 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1629 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1630 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1631 designator_skip = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1632 next = ce->value;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1633 }
111
kono
parents:
diff changeset
1634
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1635 if (ce)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1636 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1637 gcc_assert (ce->value);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1638 next = massage_init_elt (type, next, nested, flags, complain);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1639 ++idx;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1640 }
111
kono
parents:
diff changeset
1641 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1642 if (next)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1643 /* Already handled above. */;
111
kono
parents:
diff changeset
1644 else if (DECL_INITIAL (field))
kono
parents:
diff changeset
1645 {
kono
parents:
diff changeset
1646 if (skipped > 0)
kono
parents:
diff changeset
1647 {
kono
parents:
diff changeset
1648 /* We're using an NSDMI past a field with implicit
kono
parents:
diff changeset
1649 zero-init. Go back and make it explicit. */
kono
parents:
diff changeset
1650 skipped = -1;
kono
parents:
diff changeset
1651 vec_safe_truncate (v, 0);
kono
parents:
diff changeset
1652 goto restart;
kono
parents:
diff changeset
1653 }
kono
parents:
diff changeset
1654 /* C++14 aggregate NSDMI. */
kono
parents:
diff changeset
1655 next = get_nsdmi (field, /*ctor*/false, complain);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1656 if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1657 && find_placeholders (next))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1658 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
111
kono
parents:
diff changeset
1659 }
kono
parents:
diff changeset
1660 else if (type_build_ctor_call (TREE_TYPE (field)))
kono
parents:
diff changeset
1661 {
kono
parents:
diff changeset
1662 /* If this type needs constructors run for
kono
parents:
diff changeset
1663 default-initialization, we can't rely on the back end to do it
kono
parents:
diff changeset
1664 for us, so build up TARGET_EXPRs. If the type in question is
kono
parents:
diff changeset
1665 a class, just build one up; if it's an array, recurse. */
kono
parents:
diff changeset
1666 next = build_constructor (init_list_type_node, NULL);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1667 next = massage_init_elt (TREE_TYPE (field), next, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1668 complain);
111
kono
parents:
diff changeset
1669
kono
parents:
diff changeset
1670 /* Warn when some struct elements are implicitly initialized. */
kono
parents:
diff changeset
1671 if ((complain & tf_warning)
kono
parents:
diff changeset
1672 && !EMPTY_CONSTRUCTOR_P (init))
kono
parents:
diff changeset
1673 warning (OPT_Wmissing_field_initializers,
kono
parents:
diff changeset
1674 "missing initializer for member %qD", field);
kono
parents:
diff changeset
1675 }
kono
parents:
diff changeset
1676 else
kono
parents:
diff changeset
1677 {
kono
parents:
diff changeset
1678 const_tree fldtype = TREE_TYPE (field);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1679 if (TYPE_REF_P (fldtype))
111
kono
parents:
diff changeset
1680 {
kono
parents:
diff changeset
1681 if (complain & tf_error)
kono
parents:
diff changeset
1682 error ("member %qD is uninitialized reference", field);
kono
parents:
diff changeset
1683 else
kono
parents:
diff changeset
1684 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1685 }
kono
parents:
diff changeset
1686 else if (CLASSTYPE_REF_FIELDS_NEED_INIT (fldtype))
kono
parents:
diff changeset
1687 {
kono
parents:
diff changeset
1688 if (complain & tf_error)
kono
parents:
diff changeset
1689 error ("member %qD with uninitialized reference fields", field);
kono
parents:
diff changeset
1690 else
kono
parents:
diff changeset
1691 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1692 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1693 /* Do nothing for flexible array members since they need not have any
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1694 elements. Don't worry about 'skipped' because a flexarray has to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1695 be the last field. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1696 else if (TREE_CODE (fldtype) == ARRAY_TYPE && !TYPE_DOMAIN (fldtype))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1697 continue;
111
kono
parents:
diff changeset
1698
kono
parents:
diff changeset
1699 /* Warn when some struct elements are implicitly initialized
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1700 to zero. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1701 if ((complain & tf_warning)
111
kono
parents:
diff changeset
1702 && !EMPTY_CONSTRUCTOR_P (init))
kono
parents:
diff changeset
1703 warning (OPT_Wmissing_field_initializers,
kono
parents:
diff changeset
1704 "missing initializer for member %qD", field);
kono
parents:
diff changeset
1705
kono
parents:
diff changeset
1706 if (!zero_init_p (fldtype)
kono
parents:
diff changeset
1707 || skipped < 0)
kono
parents:
diff changeset
1708 next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE,
kono
parents:
diff changeset
1709 /*static_storage_p=*/false);
kono
parents:
diff changeset
1710 else
kono
parents:
diff changeset
1711 {
kono
parents:
diff changeset
1712 /* The default zero-initialization is fine for us; don't
kono
parents:
diff changeset
1713 add anything to the CONSTRUCTOR. */
kono
parents:
diff changeset
1714 skipped = 1;
kono
parents:
diff changeset
1715 continue;
kono
parents:
diff changeset
1716 }
kono
parents:
diff changeset
1717 }
kono
parents:
diff changeset
1718
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1719 if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1720 && !TREE_SIDE_EFFECTS (next))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1721 /* Don't add trivial initialization of an empty base/field to the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1722 constructor, as they might not be ordered the way the back-end
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1723 expects. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1724 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1725
111
kono
parents:
diff changeset
1726 /* If this is a bitfield, now convert to the lowered type. */
kono
parents:
diff changeset
1727 if (type != TREE_TYPE (field))
kono
parents:
diff changeset
1728 next = cp_convert_and_check (TREE_TYPE (field), next, complain);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1729 picflags |= picflag_from_initializer (next);
111
kono
parents:
diff changeset
1730 CONSTRUCTOR_APPEND_ELT (v, field, next);
kono
parents:
diff changeset
1731 }
kono
parents:
diff changeset
1732
kono
parents:
diff changeset
1733 if (idx < CONSTRUCTOR_NELTS (init))
kono
parents:
diff changeset
1734 {
kono
parents:
diff changeset
1735 if (complain & tf_error)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1736 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1737 constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1738 /* For better diagnostics, try to find out if it is really
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 the case of too many initializers or if designators are
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1740 in incorrect order. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1741 if (designator_skip == 1 && ce->index)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1742 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1743 gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1744 || identifier_p (ce->index));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1745 for (field = TYPE_FIELDS (type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1746 field; field = DECL_CHAIN (field))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1747 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1748 if (TREE_CODE (field) != FIELD_DECL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1749 || (DECL_ARTIFICIAL (field)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1750 && !(cxx_dialect >= cxx17
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1751 && DECL_FIELD_IS_BASE (field))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1752 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1753
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1754 if (DECL_UNNAMED_BIT_FIELD (field))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1755 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1756
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1757 if (ce->index == field || ce->index == DECL_NAME (field))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1758 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1759 if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1760 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1761 tree t
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1762 = search_anon_aggr (TREE_TYPE (field),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1763 TREE_CODE (ce->index) == FIELD_DECL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1764 ? DECL_NAME (ce->index)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1765 : ce->index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1766 if (t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1767 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1768 field = t;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1769 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1770 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1771 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1772 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1773 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1774 if (field)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1775 error ("designator order for field %qD does not match declaration "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1776 "order in %qT", field, type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1777 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1778 error ("too many initializers for %qT", type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1779 }
111
kono
parents:
diff changeset
1780 else
kono
parents:
diff changeset
1781 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1782 }
kono
parents:
diff changeset
1783
kono
parents:
diff changeset
1784 CONSTRUCTOR_ELTS (init) = v;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1785 return picflags;
111
kono
parents:
diff changeset
1786 }
kono
parents:
diff changeset
1787
kono
parents:
diff changeset
1788 /* Subroutine of process_init_constructor, which will process a single
kono
parents:
diff changeset
1789 initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*)
kono
parents:
diff changeset
1790 which describe the initializer. */
kono
parents:
diff changeset
1791
kono
parents:
diff changeset
1792 static int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1793 process_init_constructor_union (tree type, tree init, int nested, int flags,
111
kono
parents:
diff changeset
1794 tsubst_flags_t complain)
kono
parents:
diff changeset
1795 {
kono
parents:
diff changeset
1796 constructor_elt *ce;
kono
parents:
diff changeset
1797 int len;
kono
parents:
diff changeset
1798
kono
parents:
diff changeset
1799 /* If the initializer was empty, use the union's NSDMI if it has one.
kono
parents:
diff changeset
1800 Otherwise use default zero initialization. */
kono
parents:
diff changeset
1801 if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
kono
parents:
diff changeset
1802 {
kono
parents:
diff changeset
1803 for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
kono
parents:
diff changeset
1804 {
kono
parents:
diff changeset
1805 if (TREE_CODE (field) == FIELD_DECL
kono
parents:
diff changeset
1806 && DECL_INITIAL (field) != NULL_TREE)
kono
parents:
diff changeset
1807 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1808 tree val = get_nsdmi (field, /*in_ctor=*/false, complain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1809 if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1810 && find_placeholders (val))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1811 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1812 CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init), field, val);
111
kono
parents:
diff changeset
1813 break;
kono
parents:
diff changeset
1814 }
kono
parents:
diff changeset
1815 }
kono
parents:
diff changeset
1816
kono
parents:
diff changeset
1817 if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
kono
parents:
diff changeset
1818 return 0;
kono
parents:
diff changeset
1819 }
kono
parents:
diff changeset
1820
kono
parents:
diff changeset
1821 len = CONSTRUCTOR_ELTS (init)->length ();
kono
parents:
diff changeset
1822 if (len > 1)
kono
parents:
diff changeset
1823 {
kono
parents:
diff changeset
1824 if (!(complain & tf_error))
kono
parents:
diff changeset
1825 return PICFLAG_ERRONEOUS;
kono
parents:
diff changeset
1826 error ("too many initializers for %qT", type);
kono
parents:
diff changeset
1827 CONSTRUCTOR_ELTS (init)->block_remove (1, len-1);
kono
parents:
diff changeset
1828 }
kono
parents:
diff changeset
1829
kono
parents:
diff changeset
1830 ce = &(*CONSTRUCTOR_ELTS (init))[0];
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 /* If this element specifies a field, initialize via that field. */
kono
parents:
diff changeset
1833 if (ce->index)
kono
parents:
diff changeset
1834 {
kono
parents:
diff changeset
1835 if (TREE_CODE (ce->index) == FIELD_DECL)
kono
parents:
diff changeset
1836 ;
kono
parents:
diff changeset
1837 else if (identifier_p (ce->index))
kono
parents:
diff changeset
1838 {
kono
parents:
diff changeset
1839 /* This can happen within a cast, see g++.dg/opt/cse2.C. */
kono
parents:
diff changeset
1840 tree name = ce->index;
kono
parents:
diff changeset
1841 tree field;
kono
parents:
diff changeset
1842 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
kono
parents:
diff changeset
1843 if (DECL_NAME (field) == name)
kono
parents:
diff changeset
1844 break;
kono
parents:
diff changeset
1845 if (!field)
kono
parents:
diff changeset
1846 {
kono
parents:
diff changeset
1847 if (complain & tf_error)
kono
parents:
diff changeset
1848 error ("no field %qD found in union being initialized",
kono
parents:
diff changeset
1849 field);
kono
parents:
diff changeset
1850 ce->value = error_mark_node;
kono
parents:
diff changeset
1851 }
kono
parents:
diff changeset
1852 ce->index = field;
kono
parents:
diff changeset
1853 }
kono
parents:
diff changeset
1854 else
kono
parents:
diff changeset
1855 {
kono
parents:
diff changeset
1856 gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
kono
parents:
diff changeset
1857 || TREE_CODE (ce->index) == RANGE_EXPR);
kono
parents:
diff changeset
1858 if (complain & tf_error)
kono
parents:
diff changeset
1859 error ("index value instead of field name in union initializer");
kono
parents:
diff changeset
1860 ce->value = error_mark_node;
kono
parents:
diff changeset
1861 }
kono
parents:
diff changeset
1862 }
kono
parents:
diff changeset
1863 else
kono
parents:
diff changeset
1864 {
kono
parents:
diff changeset
1865 /* Find the first named field. ANSI decided in September 1990
kono
parents:
diff changeset
1866 that only named fields count here. */
kono
parents:
diff changeset
1867 tree field = TYPE_FIELDS (type);
kono
parents:
diff changeset
1868 while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
kono
parents:
diff changeset
1869 field = TREE_CHAIN (field);
kono
parents:
diff changeset
1870 if (field == NULL_TREE)
kono
parents:
diff changeset
1871 {
kono
parents:
diff changeset
1872 if (complain & tf_error)
kono
parents:
diff changeset
1873 error ("too many initializers for %qT", type);
kono
parents:
diff changeset
1874 ce->value = error_mark_node;
kono
parents:
diff changeset
1875 }
kono
parents:
diff changeset
1876 ce->index = field;
kono
parents:
diff changeset
1877 }
kono
parents:
diff changeset
1878
kono
parents:
diff changeset
1879 if (ce->value && ce->value != error_mark_node)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1880 ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1881 flags, complain);
111
kono
parents:
diff changeset
1882
kono
parents:
diff changeset
1883 return picflag_from_initializer (ce->value);
kono
parents:
diff changeset
1884 }
kono
parents:
diff changeset
1885
kono
parents:
diff changeset
1886 /* Process INIT, a constructor for a variable of aggregate type TYPE. The
kono
parents:
diff changeset
1887 constructor is a brace-enclosed initializer, and will be modified in-place.
kono
parents:
diff changeset
1888
kono
parents:
diff changeset
1889 Each element is converted to the right type through digest_init, and
kono
parents:
diff changeset
1890 missing initializers are added following the language rules (zero-padding,
kono
parents:
diff changeset
1891 etc.).
kono
parents:
diff changeset
1892
kono
parents:
diff changeset
1893 After the execution, the initializer will have TREE_CONSTANT if all elts are
kono
parents:
diff changeset
1894 constant, and TREE_STATIC set if, in addition, all elts are simple enough
kono
parents:
diff changeset
1895 constants that the assembler and linker can compute them.
kono
parents:
diff changeset
1896
kono
parents:
diff changeset
1897 The function returns the initializer itself, or error_mark_node in case
kono
parents:
diff changeset
1898 of error. */
kono
parents:
diff changeset
1899
kono
parents:
diff changeset
1900 static tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1901 process_init_constructor (tree type, tree init, int nested, int flags,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1902 tsubst_flags_t complain)
111
kono
parents:
diff changeset
1903 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1904 int picflags;
111
kono
parents:
diff changeset
1905
kono
parents:
diff changeset
1906 gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
kono
parents:
diff changeset
1907
kono
parents:
diff changeset
1908 if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1909 picflags = process_init_constructor_array (type, init, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1910 complain);
111
kono
parents:
diff changeset
1911 else if (TREE_CODE (type) == RECORD_TYPE)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1912 picflags = process_init_constructor_record (type, init, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1913 complain);
111
kono
parents:
diff changeset
1914 else if (TREE_CODE (type) == UNION_TYPE)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1915 picflags = process_init_constructor_union (type, init, nested, flags,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1916 complain);
111
kono
parents:
diff changeset
1917 else
kono
parents:
diff changeset
1918 gcc_unreachable ();
kono
parents:
diff changeset
1919
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1920 if (picflags & PICFLAG_ERRONEOUS)
111
kono
parents:
diff changeset
1921 return error_mark_node;
kono
parents:
diff changeset
1922
kono
parents:
diff changeset
1923 TREE_TYPE (init) = type;
kono
parents:
diff changeset
1924 if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
kono
parents:
diff changeset
1925 cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1926 if (picflags & PICFLAG_SIDE_EFFECTS)
111
kono
parents:
diff changeset
1927 {
kono
parents:
diff changeset
1928 TREE_CONSTANT (init) = false;
kono
parents:
diff changeset
1929 TREE_SIDE_EFFECTS (init) = true;
kono
parents:
diff changeset
1930 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1931 else if (picflags & PICFLAG_NOT_ALL_CONSTANT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1932 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1933 /* Make sure TREE_CONSTANT isn't set from build_constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1934 TREE_CONSTANT (init) = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1935 TREE_SIDE_EFFECTS (init) = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1936 }
111
kono
parents:
diff changeset
1937 else
kono
parents:
diff changeset
1938 {
kono
parents:
diff changeset
1939 TREE_CONSTANT (init) = 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1940 TREE_SIDE_EFFECTS (init) = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1941 if (!(picflags & PICFLAG_NOT_ALL_SIMPLE))
111
kono
parents:
diff changeset
1942 TREE_STATIC (init) = 1;
kono
parents:
diff changeset
1943 }
kono
parents:
diff changeset
1944 return init;
kono
parents:
diff changeset
1945 }
kono
parents:
diff changeset
1946
kono
parents:
diff changeset
1947 /* Given a structure or union value DATUM, construct and return
kono
parents:
diff changeset
1948 the structure or union component which results from narrowing
kono
parents:
diff changeset
1949 that value to the base specified in BASETYPE. For example, given the
kono
parents:
diff changeset
1950 hierarchy
kono
parents:
diff changeset
1951
kono
parents:
diff changeset
1952 class L { int ii; };
kono
parents:
diff changeset
1953 class A : L { ... };
kono
parents:
diff changeset
1954 class B : L { ... };
kono
parents:
diff changeset
1955 class C : A, B { ... };
kono
parents:
diff changeset
1956
kono
parents:
diff changeset
1957 and the declaration
kono
parents:
diff changeset
1958
kono
parents:
diff changeset
1959 C x;
kono
parents:
diff changeset
1960
kono
parents:
diff changeset
1961 then the expression
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 x.A::ii refers to the ii member of the L part of
kono
parents:
diff changeset
1964 the A part of the C object named by X. In this case,
kono
parents:
diff changeset
1965 DATUM would be x, and BASETYPE would be A.
kono
parents:
diff changeset
1966
kono
parents:
diff changeset
1967 I used to think that this was nonconformant, that the standard specified
kono
parents:
diff changeset
1968 that first we look up ii in A, then convert x to an L& and pull out the
kono
parents:
diff changeset
1969 ii part. But in fact, it does say that we convert x to an A&; A here
kono
parents:
diff changeset
1970 is known as the "naming class". (jason 2000-12-19)
kono
parents:
diff changeset
1971
kono
parents:
diff changeset
1972 BINFO_P points to a variable initialized either to NULL_TREE or to the
kono
parents:
diff changeset
1973 binfo for the specific base subobject we want to convert to. */
kono
parents:
diff changeset
1974
kono
parents:
diff changeset
1975 tree
kono
parents:
diff changeset
1976 build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
kono
parents:
diff changeset
1977 {
kono
parents:
diff changeset
1978 tree binfo;
kono
parents:
diff changeset
1979
kono
parents:
diff changeset
1980 if (datum == error_mark_node)
kono
parents:
diff changeset
1981 return error_mark_node;
kono
parents:
diff changeset
1982 if (*binfo_p)
kono
parents:
diff changeset
1983 binfo = *binfo_p;
kono
parents:
diff changeset
1984 else
kono
parents:
diff changeset
1985 binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check,
kono
parents:
diff changeset
1986 NULL, tf_warning_or_error);
kono
parents:
diff changeset
1987
kono
parents:
diff changeset
1988 if (!binfo || binfo == error_mark_node)
kono
parents:
diff changeset
1989 {
kono
parents:
diff changeset
1990 *binfo_p = NULL_TREE;
kono
parents:
diff changeset
1991 if (!binfo)
kono
parents:
diff changeset
1992 error_not_base_type (basetype, TREE_TYPE (datum));
kono
parents:
diff changeset
1993 return error_mark_node;
kono
parents:
diff changeset
1994 }
kono
parents:
diff changeset
1995
kono
parents:
diff changeset
1996 *binfo_p = binfo;
kono
parents:
diff changeset
1997 return build_base_path (PLUS_EXPR, datum, binfo, 1,
kono
parents:
diff changeset
1998 tf_warning_or_error);
kono
parents:
diff changeset
1999 }
kono
parents:
diff changeset
2000
kono
parents:
diff changeset
2001 /* Build a reference to an object specified by the C++ `->' operator.
kono
parents:
diff changeset
2002 Usually this just involves dereferencing the object, but if the
kono
parents:
diff changeset
2003 `->' operator is overloaded, then such overloads must be
kono
parents:
diff changeset
2004 performed until an object which does not have the `->' operator
kono
parents:
diff changeset
2005 overloaded is found. An error is reported when circular pointer
kono
parents:
diff changeset
2006 delegation is detected. */
kono
parents:
diff changeset
2007
kono
parents:
diff changeset
2008 tree
kono
parents:
diff changeset
2009 build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
kono
parents:
diff changeset
2010 {
kono
parents:
diff changeset
2011 tree orig_expr = expr;
kono
parents:
diff changeset
2012 tree type = TREE_TYPE (expr);
kono
parents:
diff changeset
2013 tree last_rval = NULL_TREE;
kono
parents:
diff changeset
2014 vec<tree, va_gc> *types_memoized = NULL;
kono
parents:
diff changeset
2015
kono
parents:
diff changeset
2016 if (type == error_mark_node)
kono
parents:
diff changeset
2017 return error_mark_node;
kono
parents:
diff changeset
2018
kono
parents:
diff changeset
2019 if (processing_template_decl)
kono
parents:
diff changeset
2020 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2021 if (type && TYPE_PTR_P (type)
111
kono
parents:
diff changeset
2022 && !dependent_scope_p (TREE_TYPE (type)))
kono
parents:
diff changeset
2023 /* Pointer to current instantiation, don't treat as dependent. */;
kono
parents:
diff changeset
2024 else if (type_dependent_expression_p (expr))
kono
parents:
diff changeset
2025 return build_min_nt_loc (loc, ARROW_EXPR, expr);
kono
parents:
diff changeset
2026 expr = build_non_dependent_expr (expr);
kono
parents:
diff changeset
2027 }
kono
parents:
diff changeset
2028
kono
parents:
diff changeset
2029 if (MAYBE_CLASS_TYPE_P (type))
kono
parents:
diff changeset
2030 {
kono
parents:
diff changeset
2031 struct tinst_level *actual_inst = current_instantiation ();
kono
parents:
diff changeset
2032 tree fn = NULL;
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 while ((expr = build_new_op (loc, COMPONENT_REF,
kono
parents:
diff changeset
2035 LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE,
kono
parents:
diff changeset
2036 &fn, complain)))
kono
parents:
diff changeset
2037 {
kono
parents:
diff changeset
2038 if (expr == error_mark_node)
kono
parents:
diff changeset
2039 return error_mark_node;
kono
parents:
diff changeset
2040
kono
parents:
diff changeset
2041 /* This provides a better instantiation backtrace in case of
kono
parents:
diff changeset
2042 error. */
kono
parents:
diff changeset
2043 if (fn && DECL_USE_TEMPLATE (fn))
kono
parents:
diff changeset
2044 push_tinst_level_loc (fn,
kono
parents:
diff changeset
2045 (current_instantiation () != actual_inst)
kono
parents:
diff changeset
2046 ? DECL_SOURCE_LOCATION (fn)
kono
parents:
diff changeset
2047 : input_location);
kono
parents:
diff changeset
2048 fn = NULL;
kono
parents:
diff changeset
2049
kono
parents:
diff changeset
2050 if (vec_member (TREE_TYPE (expr), types_memoized))
kono
parents:
diff changeset
2051 {
kono
parents:
diff changeset
2052 if (complain & tf_error)
kono
parents:
diff changeset
2053 error ("circular pointer delegation detected");
kono
parents:
diff changeset
2054 return error_mark_node;
kono
parents:
diff changeset
2055 }
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 vec_safe_push (types_memoized, TREE_TYPE (expr));
kono
parents:
diff changeset
2058 last_rval = expr;
kono
parents:
diff changeset
2059 }
kono
parents:
diff changeset
2060
kono
parents:
diff changeset
2061 while (current_instantiation () != actual_inst)
kono
parents:
diff changeset
2062 pop_tinst_level ();
kono
parents:
diff changeset
2063
kono
parents:
diff changeset
2064 if (last_rval == NULL_TREE)
kono
parents:
diff changeset
2065 {
kono
parents:
diff changeset
2066 if (complain & tf_error)
kono
parents:
diff changeset
2067 error ("base operand of %<->%> has non-pointer type %qT", type);
kono
parents:
diff changeset
2068 return error_mark_node;
kono
parents:
diff changeset
2069 }
kono
parents:
diff changeset
2070
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2071 if (TYPE_REF_P (TREE_TYPE (last_rval)))
111
kono
parents:
diff changeset
2072 last_rval = convert_from_reference (last_rval);
kono
parents:
diff changeset
2073 }
kono
parents:
diff changeset
2074 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2075 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2076 last_rval = decay_conversion (expr, complain);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2077 if (last_rval == error_mark_node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2078 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2079 }
111
kono
parents:
diff changeset
2080
kono
parents:
diff changeset
2081 if (TYPE_PTR_P (TREE_TYPE (last_rval)))
kono
parents:
diff changeset
2082 {
kono
parents:
diff changeset
2083 if (processing_template_decl)
kono
parents:
diff changeset
2084 {
kono
parents:
diff changeset
2085 expr = build_min (ARROW_EXPR, TREE_TYPE (TREE_TYPE (last_rval)),
kono
parents:
diff changeset
2086 orig_expr);
kono
parents:
diff changeset
2087 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (last_rval);
kono
parents:
diff changeset
2088 return expr;
kono
parents:
diff changeset
2089 }
kono
parents:
diff changeset
2090
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2091 return cp_build_indirect_ref (loc, last_rval, RO_ARROW, complain);
111
kono
parents:
diff changeset
2092 }
kono
parents:
diff changeset
2093
kono
parents:
diff changeset
2094 if (complain & tf_error)
kono
parents:
diff changeset
2095 {
kono
parents:
diff changeset
2096 if (types_memoized)
kono
parents:
diff changeset
2097 error ("result of %<operator->()%> yields non-pointer result");
kono
parents:
diff changeset
2098 else
kono
parents:
diff changeset
2099 error ("base operand of %<->%> is not a pointer");
kono
parents:
diff changeset
2100 }
kono
parents:
diff changeset
2101 return error_mark_node;
kono
parents:
diff changeset
2102 }
kono
parents:
diff changeset
2103
kono
parents:
diff changeset
2104 /* Return an expression for "DATUM .* COMPONENT". DATUM has not
kono
parents:
diff changeset
2105 already been checked out to be of aggregate type. */
kono
parents:
diff changeset
2106
kono
parents:
diff changeset
2107 tree
kono
parents:
diff changeset
2108 build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
kono
parents:
diff changeset
2109 {
kono
parents:
diff changeset
2110 tree ptrmem_type;
kono
parents:
diff changeset
2111 tree objtype;
kono
parents:
diff changeset
2112 tree type;
kono
parents:
diff changeset
2113 tree binfo;
kono
parents:
diff changeset
2114 tree ctype;
kono
parents:
diff changeset
2115
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2116 datum = mark_lvalue_use (datum);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2117 component = mark_rvalue_use (component);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2118
111
kono
parents:
diff changeset
2119 if (error_operand_p (datum) || error_operand_p (component))
kono
parents:
diff changeset
2120 return error_mark_node;
kono
parents:
diff changeset
2121
kono
parents:
diff changeset
2122 ptrmem_type = TREE_TYPE (component);
kono
parents:
diff changeset
2123 if (!TYPE_PTRMEM_P (ptrmem_type))
kono
parents:
diff changeset
2124 {
kono
parents:
diff changeset
2125 if (complain & tf_error)
kono
parents:
diff changeset
2126 error ("%qE cannot be used as a member pointer, since it is of "
kono
parents:
diff changeset
2127 "type %qT", component, ptrmem_type);
kono
parents:
diff changeset
2128 return error_mark_node;
kono
parents:
diff changeset
2129 }
kono
parents:
diff changeset
2130
kono
parents:
diff changeset
2131 objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
kono
parents:
diff changeset
2132 if (! MAYBE_CLASS_TYPE_P (objtype))
kono
parents:
diff changeset
2133 {
kono
parents:
diff changeset
2134 if (complain & tf_error)
kono
parents:
diff changeset
2135 error ("cannot apply member pointer %qE to %qE, which is of "
kono
parents:
diff changeset
2136 "non-class type %qT", component, datum, objtype);
kono
parents:
diff changeset
2137 return error_mark_node;
kono
parents:
diff changeset
2138 }
kono
parents:
diff changeset
2139
kono
parents:
diff changeset
2140 type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
kono
parents:
diff changeset
2141 ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));
kono
parents:
diff changeset
2142
kono
parents:
diff changeset
2143 if (!COMPLETE_TYPE_P (ctype))
kono
parents:
diff changeset
2144 {
kono
parents:
diff changeset
2145 if (!same_type_p (ctype, objtype))
kono
parents:
diff changeset
2146 goto mismatch;
kono
parents:
diff changeset
2147 binfo = NULL;
kono
parents:
diff changeset
2148 }
kono
parents:
diff changeset
2149 else
kono
parents:
diff changeset
2150 {
kono
parents:
diff changeset
2151 binfo = lookup_base (objtype, ctype, ba_check, NULL, complain);
kono
parents:
diff changeset
2152
kono
parents:
diff changeset
2153 if (!binfo)
kono
parents:
diff changeset
2154 {
kono
parents:
diff changeset
2155 mismatch:
kono
parents:
diff changeset
2156 if (complain & tf_error)
kono
parents:
diff changeset
2157 error ("pointer to member type %qT incompatible with object "
kono
parents:
diff changeset
2158 "type %qT", type, objtype);
kono
parents:
diff changeset
2159 return error_mark_node;
kono
parents:
diff changeset
2160 }
kono
parents:
diff changeset
2161 else if (binfo == error_mark_node)
kono
parents:
diff changeset
2162 return error_mark_node;
kono
parents:
diff changeset
2163 }
kono
parents:
diff changeset
2164
kono
parents:
diff changeset
2165 if (TYPE_PTRDATAMEM_P (ptrmem_type))
kono
parents:
diff changeset
2166 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2167 bool is_lval = real_lvalue_p (datum);
111
kono
parents:
diff changeset
2168 tree ptype;
kono
parents:
diff changeset
2169
kono
parents:
diff changeset
2170 /* Compute the type of the field, as described in [expr.ref].
kono
parents:
diff changeset
2171 There's no such thing as a mutable pointer-to-member, so
kono
parents:
diff changeset
2172 things are not as complex as they are for references to
kono
parents:
diff changeset
2173 non-static data members. */
kono
parents:
diff changeset
2174 type = cp_build_qualified_type (type,
kono
parents:
diff changeset
2175 (cp_type_quals (type)
kono
parents:
diff changeset
2176 | cp_type_quals (TREE_TYPE (datum))));
kono
parents:
diff changeset
2177
kono
parents:
diff changeset
2178 datum = build_address (datum);
kono
parents:
diff changeset
2179
kono
parents:
diff changeset
2180 /* Convert object to the correct base. */
kono
parents:
diff changeset
2181 if (binfo)
kono
parents:
diff changeset
2182 {
kono
parents:
diff changeset
2183 datum = build_base_path (PLUS_EXPR, datum, binfo, 1, complain);
kono
parents:
diff changeset
2184 if (datum == error_mark_node)
kono
parents:
diff changeset
2185 return error_mark_node;
kono
parents:
diff changeset
2186 }
kono
parents:
diff changeset
2187
kono
parents:
diff changeset
2188 /* Build an expression for "object + offset" where offset is the
kono
parents:
diff changeset
2189 value stored in the pointer-to-data-member. */
kono
parents:
diff changeset
2190 ptype = build_pointer_type (type);
kono
parents:
diff changeset
2191 datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2192 datum = cp_build_fold_indirect_ref (datum);
111
kono
parents:
diff changeset
2193 if (datum == error_mark_node)
kono
parents:
diff changeset
2194 return error_mark_node;
kono
parents:
diff changeset
2195
kono
parents:
diff changeset
2196 /* If the object expression was an rvalue, return an rvalue. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2197 if (!is_lval)
111
kono
parents:
diff changeset
2198 datum = move (datum);
kono
parents:
diff changeset
2199 return datum;
kono
parents:
diff changeset
2200 }
kono
parents:
diff changeset
2201 else
kono
parents:
diff changeset
2202 {
kono
parents:
diff changeset
2203 /* 5.5/6: In a .* expression whose object expression is an rvalue, the
kono
parents:
diff changeset
2204 program is ill-formed if the second operand is a pointer to member
kono
parents:
diff changeset
2205 function with ref-qualifier & (for C++2A: unless its cv-qualifier-seq
kono
parents:
diff changeset
2206 is const). In a .* expression whose object expression is an lvalue,
kono
parents:
diff changeset
2207 the program is ill-formed if the second operand is a pointer to member
kono
parents:
diff changeset
2208 function with ref-qualifier &&. */
kono
parents:
diff changeset
2209 if (FUNCTION_REF_QUALIFIED (type))
kono
parents:
diff changeset
2210 {
kono
parents:
diff changeset
2211 bool lval = lvalue_p (datum);
kono
parents:
diff changeset
2212 if (lval && FUNCTION_RVALUE_QUALIFIED (type))
kono
parents:
diff changeset
2213 {
kono
parents:
diff changeset
2214 if (complain & tf_error)
kono
parents:
diff changeset
2215 error ("pointer-to-member-function type %qT requires an rvalue",
kono
parents:
diff changeset
2216 ptrmem_type);
kono
parents:
diff changeset
2217 return error_mark_node;
kono
parents:
diff changeset
2218 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2219 else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
111
kono
parents:
diff changeset
2220 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2221 if ((type_memfn_quals (type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2222 & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2223 != TYPE_QUAL_CONST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2224 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2225 if (complain & tf_error)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2226 error ("pointer-to-member-function type %qT requires "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2227 "an lvalue", ptrmem_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2228 return error_mark_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2229 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2230 else if (cxx_dialect < cxx2a)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2231 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2232 if (complain & tf_warning_or_error)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2233 pedwarn (input_location, OPT_Wpedantic,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2234 "pointer-to-member-function type %qT requires "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2235 "an lvalue before C++2a", ptrmem_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2236 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2237 return error_mark_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2238 }
111
kono
parents:
diff changeset
2239 }
kono
parents:
diff changeset
2240 }
kono
parents:
diff changeset
2241 return build2 (OFFSET_REF, type, datum, component);
kono
parents:
diff changeset
2242 }
kono
parents:
diff changeset
2243 }
kono
parents:
diff changeset
2244
kono
parents:
diff changeset
2245 /* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
kono
parents:
diff changeset
2246
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2247 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2248 build_functional_cast_1 (location_t loc, tree exp, tree parms,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2249 tsubst_flags_t complain)
111
kono
parents:
diff changeset
2250 {
kono
parents:
diff changeset
2251 /* This is either a call to a constructor,
kono
parents:
diff changeset
2252 or a C cast in C++'s `functional' notation. */
kono
parents:
diff changeset
2253
kono
parents:
diff changeset
2254 /* The type to which we are casting. */
kono
parents:
diff changeset
2255 tree type;
kono
parents:
diff changeset
2256
kono
parents:
diff changeset
2257 if (error_operand_p (exp) || parms == error_mark_node)
kono
parents:
diff changeset
2258 return error_mark_node;
kono
parents:
diff changeset
2259
kono
parents:
diff changeset
2260 if (TREE_CODE (exp) == TYPE_DECL)
kono
parents:
diff changeset
2261 {
kono
parents:
diff changeset
2262 type = TREE_TYPE (exp);
kono
parents:
diff changeset
2263
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2264 if (DECL_ARTIFICIAL (exp))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2265 cp_warn_deprecated_use (type);
111
kono
parents:
diff changeset
2266 }
kono
parents:
diff changeset
2267 else
kono
parents:
diff changeset
2268 type = exp;
kono
parents:
diff changeset
2269
kono
parents:
diff changeset
2270 /* We need to check this explicitly, since value-initialization of
kono
parents:
diff changeset
2271 arrays is allowed in other situations. */
kono
parents:
diff changeset
2272 if (TREE_CODE (type) == ARRAY_TYPE)
kono
parents:
diff changeset
2273 {
kono
parents:
diff changeset
2274 if (complain & tf_error)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2275 error_at (loc, "functional cast to array type %qT", type);
111
kono
parents:
diff changeset
2276 return error_mark_node;
kono
parents:
diff changeset
2277 }
kono
parents:
diff changeset
2278
kono
parents:
diff changeset
2279 if (tree anode = type_uses_auto (type))
kono
parents:
diff changeset
2280 {
kono
parents:
diff changeset
2281 if (!CLASS_PLACEHOLDER_TEMPLATE (anode))
kono
parents:
diff changeset
2282 {
kono
parents:
diff changeset
2283 if (complain & tf_error)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2284 error_at (loc, "invalid use of %qT", anode);
111
kono
parents:
diff changeset
2285 return error_mark_node;
kono
parents:
diff changeset
2286 }
kono
parents:
diff changeset
2287 else if (!parms)
kono
parents:
diff changeset
2288 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2289 /* Even if there are no parameters, we might be able to deduce from
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2290 default template arguments. Pass TF_NONE so that we don't
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2291 generate redundant diagnostics. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2292 type = do_auto_deduction (type, parms, anode, tf_none,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2293 adc_variable_type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2294 if (type == error_mark_node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2295 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2296 if (complain & tf_error)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2297 error_at (loc, "cannot deduce template arguments "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2298 "for %qT from %<()%>", anode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2299 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2300 }
111
kono
parents:
diff changeset
2301 }
kono
parents:
diff changeset
2302 else
kono
parents:
diff changeset
2303 type = do_auto_deduction (type, parms, anode, complain,
kono
parents:
diff changeset
2304 adc_variable_type);
kono
parents:
diff changeset
2305 }
kono
parents:
diff changeset
2306
kono
parents:
diff changeset
2307 if (processing_template_decl)
kono
parents:
diff changeset
2308 {
kono
parents:
diff changeset
2309 tree t;
kono
parents:
diff changeset
2310
kono
parents:
diff changeset
2311 /* Diagnose this even in a template. We could also try harder
kono
parents:
diff changeset
2312 to give all the usual errors when the type and args are
kono
parents:
diff changeset
2313 non-dependent... */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2314 if (TYPE_REF_P (type) && !parms)
111
kono
parents:
diff changeset
2315 {
kono
parents:
diff changeset
2316 if (complain & tf_error)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2317 error_at (loc, "invalid value-initialization of reference type");
111
kono
parents:
diff changeset
2318 return error_mark_node;
kono
parents:
diff changeset
2319 }
kono
parents:
diff changeset
2320
kono
parents:
diff changeset
2321 t = build_min (CAST_EXPR, type, parms);
kono
parents:
diff changeset
2322 /* We don't know if it will or will not have side effects. */
kono
parents:
diff changeset
2323 TREE_SIDE_EFFECTS (t) = 1;
kono
parents:
diff changeset
2324 return t;
kono
parents:
diff changeset
2325 }
kono
parents:
diff changeset
2326
kono
parents:
diff changeset
2327 if (! MAYBE_CLASS_TYPE_P (type))
kono
parents:
diff changeset
2328 {
kono
parents:
diff changeset
2329 if (parms == NULL_TREE)
kono
parents:
diff changeset
2330 {
kono
parents:
diff changeset
2331 if (VOID_TYPE_P (type))
kono
parents:
diff changeset
2332 return void_node;
kono
parents:
diff changeset
2333 return build_value_init (cv_unqualified (type), complain);
kono
parents:
diff changeset
2334 }
kono
parents:
diff changeset
2335
kono
parents:
diff changeset
2336 /* This must build a C cast. */
kono
parents:
diff changeset
2337 parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2338 return cp_build_c_cast (loc, type, parms, complain);
111
kono
parents:
diff changeset
2339 }
kono
parents:
diff changeset
2340
kono
parents:
diff changeset
2341 /* Prepare to evaluate as a call to a constructor. If this expression
kono
parents:
diff changeset
2342 is actually used, for example,
kono
parents:
diff changeset
2343
kono
parents:
diff changeset
2344 return X (arg1, arg2, ...);
kono
parents:
diff changeset
2345
kono
parents:
diff changeset
2346 then the slot being initialized will be filled in. */
kono
parents:
diff changeset
2347
kono
parents:
diff changeset
2348 if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
kono
parents:
diff changeset
2349 return error_mark_node;
kono
parents:
diff changeset
2350 if (abstract_virtuals_error_sfinae (ACU_CAST, type, complain))
kono
parents:
diff changeset
2351 return error_mark_node;
kono
parents:
diff changeset
2352
kono
parents:
diff changeset
2353 /* [expr.type.conv]
kono
parents:
diff changeset
2354
kono
parents:
diff changeset
2355 If the expression list is a single-expression, the type
kono
parents:
diff changeset
2356 conversion is equivalent (in definedness, and if defined in
kono
parents:
diff changeset
2357 meaning) to the corresponding cast expression. */
kono
parents:
diff changeset
2358 if (parms && TREE_CHAIN (parms) == NULL_TREE)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2359 return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);
111
kono
parents:
diff changeset
2360
kono
parents:
diff changeset
2361 /* [expr.type.conv]
kono
parents:
diff changeset
2362
kono
parents:
diff changeset
2363 The expression T(), where T is a simple-type-specifier for a
kono
parents:
diff changeset
2364 non-array complete object type or the (possibly cv-qualified)
kono
parents:
diff changeset
2365 void type, creates an rvalue of the specified type, which is
kono
parents:
diff changeset
2366 value-initialized. */
kono
parents:
diff changeset
2367
kono
parents:
diff changeset
2368 if (parms == NULL_TREE)
kono
parents:
diff changeset
2369 {
kono
parents:
diff changeset
2370 exp = build_value_init (type, complain);
kono
parents:
diff changeset
2371 exp = get_target_expr_sfinae (exp, complain);
kono
parents:
diff changeset
2372 return exp;
kono
parents:
diff changeset
2373 }
kono
parents:
diff changeset
2374
kono
parents:
diff changeset
2375 /* Call the constructor. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2376 releasing_vec parmvec;
111
kono
parents:
diff changeset
2377 for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
kono
parents:
diff changeset
2378 vec_safe_push (parmvec, TREE_VALUE (parms));
kono
parents:
diff changeset
2379 exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
kono
parents:
diff changeset
2380 &parmvec, type, LOOKUP_NORMAL, complain);
kono
parents:
diff changeset
2381
kono
parents:
diff changeset
2382 if (exp == error_mark_node)
kono
parents:
diff changeset
2383 return error_mark_node;
kono
parents:
diff changeset
2384
kono
parents:
diff changeset
2385 return build_cplus_new (type, exp, complain);
kono
parents:
diff changeset
2386 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2387
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2388 tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2389 build_functional_cast (location_t loc, tree exp, tree parms,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2390 tsubst_flags_t complain)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2391 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2392 tree result = build_functional_cast_1 (loc, exp, parms, complain);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2393 protected_set_expr_location (result, loc);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2394 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2395 }
111
kono
parents:
diff changeset
2396
kono
parents:
diff changeset
2397
kono
parents:
diff changeset
2398 /* Add new exception specifier SPEC, to the LIST we currently have.
kono
parents:
diff changeset
2399 If it's already in LIST then do nothing.
kono
parents:
diff changeset
2400 Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
kono
parents:
diff changeset
2401 know what we're doing. */
kono
parents:
diff changeset
2402
kono
parents:
diff changeset
2403 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2404 add_exception_specifier (tree list, tree spec, tsubst_flags_t complain)
111
kono
parents:
diff changeset
2405 {
kono
parents:
diff changeset
2406 bool ok;
kono
parents:
diff changeset
2407 tree core = spec;
kono
parents:
diff changeset
2408 bool is_ptr;
kono
parents:
diff changeset
2409 diagnostic_t diag_type = DK_UNSPECIFIED; /* none */
kono
parents:
diff changeset
2410
kono
parents:
diff changeset
2411 if (spec == error_mark_node)
kono
parents:
diff changeset
2412 return list;
kono
parents:
diff changeset
2413
kono
parents:
diff changeset
2414 gcc_assert (spec && (!list || TREE_VALUE (list)));
kono
parents:
diff changeset
2415
kono
parents:
diff changeset
2416 /* [except.spec] 1, type in an exception specifier shall not be
kono
parents:
diff changeset
2417 incomplete, or pointer or ref to incomplete other than pointer
kono
parents:
diff changeset
2418 to cv void. */
kono
parents:
diff changeset
2419 is_ptr = TYPE_PTR_P (core);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2420 if (is_ptr || TYPE_REF_P (core))
111
kono
parents:
diff changeset
2421 core = TREE_TYPE (core);
kono
parents:
diff changeset
2422 if (complain < 0)
kono
parents:
diff changeset
2423 ok = true;
kono
parents:
diff changeset
2424 else if (VOID_TYPE_P (core))
kono
parents:
diff changeset
2425 ok = is_ptr;
kono
parents:
diff changeset
2426 else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
kono
parents:
diff changeset
2427 ok = true;
kono
parents:
diff changeset
2428 else if (processing_template_decl)
kono
parents:
diff changeset
2429 ok = true;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2430 else if (!verify_type_context (input_location, TCTX_EXCEPTIONS, core,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2431 !(complain & tf_error)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2432 return error_mark_node;
111
kono
parents:
diff changeset
2433 else
kono
parents:
diff changeset
2434 {
kono
parents:
diff changeset
2435 ok = true;
kono
parents:
diff changeset
2436 /* 15.4/1 says that types in an exception specifier must be complete,
kono
parents:
diff changeset
2437 but it seems more reasonable to only require this on definitions
kono
parents:
diff changeset
2438 and calls. So just give a pedwarn at this point; we will give an
kono
parents:
diff changeset
2439 error later if we hit one of those two cases. */
kono
parents:
diff changeset
2440 if (!COMPLETE_TYPE_P (complete_type (core)))
kono
parents:
diff changeset
2441 diag_type = DK_PEDWARN; /* pedwarn */
kono
parents:
diff changeset
2442 }
kono
parents:
diff changeset
2443
kono
parents:
diff changeset
2444 if (ok)
kono
parents:
diff changeset
2445 {
kono
parents:
diff changeset
2446 tree probe;
kono
parents:
diff changeset
2447
kono
parents:
diff changeset
2448 for (probe = list; probe; probe = TREE_CHAIN (probe))
kono
parents:
diff changeset
2449 if (same_type_p (TREE_VALUE (probe), spec))
kono
parents:
diff changeset
2450 break;
kono
parents:
diff changeset
2451 if (!probe)
kono
parents:
diff changeset
2452 list = tree_cons (NULL_TREE, spec, list);
kono
parents:
diff changeset
2453 }
kono
parents:
diff changeset
2454 else
kono
parents:
diff changeset
2455 diag_type = DK_ERROR; /* error */
kono
parents:
diff changeset
2456
kono
parents:
diff changeset
2457 if (diag_type != DK_UNSPECIFIED
kono
parents:
diff changeset
2458 && (complain & tf_warning_or_error))
kono
parents:
diff changeset
2459 cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);
kono
parents:
diff changeset
2460
kono
parents:
diff changeset
2461 return list;
kono
parents:
diff changeset
2462 }
kono
parents:
diff changeset
2463
kono
parents:
diff changeset
2464 /* Like nothrow_spec_p, but don't abort on deferred noexcept. */
kono
parents:
diff changeset
2465
kono
parents:
diff changeset
2466 static bool
kono
parents:
diff changeset
2467 nothrow_spec_p_uninst (const_tree spec)
kono
parents:
diff changeset
2468 {
kono
parents:
diff changeset
2469 if (DEFERRED_NOEXCEPT_SPEC_P (spec))
kono
parents:
diff changeset
2470 return false;
kono
parents:
diff changeset
2471 return nothrow_spec_p (spec);
kono
parents:
diff changeset
2472 }
kono
parents:
diff changeset
2473
kono
parents:
diff changeset
2474 /* Combine the two exceptions specifier lists LIST and ADD, and return
kono
parents:
diff changeset
2475 their union. */
kono
parents:
diff changeset
2476
kono
parents:
diff changeset
2477 tree
kono
parents:
diff changeset
2478 merge_exception_specifiers (tree list, tree add)
kono
parents:
diff changeset
2479 {
kono
parents:
diff changeset
2480 tree noex, orig_list;
kono
parents:
diff changeset
2481
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2482 if (list == error_mark_node || add == error_mark_node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2483 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2484
111
kono
parents:
diff changeset
2485 /* No exception-specifier or noexcept(false) are less strict than
kono
parents:
diff changeset
2486 anything else. Prefer the newer variant (LIST). */
kono
parents:
diff changeset
2487 if (!list || list == noexcept_false_spec)
kono
parents:
diff changeset
2488 return list;
kono
parents:
diff changeset
2489 else if (!add || add == noexcept_false_spec)
kono
parents:
diff changeset
2490 return add;
kono
parents:
diff changeset
2491
kono
parents:
diff changeset
2492 /* noexcept(true) and throw() are stricter than anything else.
kono
parents:
diff changeset
2493 As above, prefer the more recent one (LIST). */
kono
parents:
diff changeset
2494 if (nothrow_spec_p_uninst (add))
kono
parents:
diff changeset
2495 return list;
kono
parents:
diff changeset
2496
kono
parents:
diff changeset
2497 /* Two implicit noexcept specs (e.g. on a destructor) are equivalent. */
kono
parents:
diff changeset
2498 if (UNEVALUATED_NOEXCEPT_SPEC_P (add)
kono
parents:
diff changeset
2499 && UNEVALUATED_NOEXCEPT_SPEC_P (list))
kono
parents:
diff changeset
2500 return list;
kono
parents:
diff changeset
2501 /* We should have instantiated other deferred noexcept specs by now. */
kono
parents:
diff changeset
2502 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (add));
kono
parents:
diff changeset
2503
kono
parents:
diff changeset
2504 if (nothrow_spec_p_uninst (list))
kono
parents:
diff changeset
2505 return add;
kono
parents:
diff changeset
2506 noex = TREE_PURPOSE (list);
kono
parents:
diff changeset
2507 gcc_checking_assert (!TREE_PURPOSE (add)
kono
parents:
diff changeset
2508 || errorcount || !flag_exceptions
kono
parents:
diff changeset
2509 || cp_tree_equal (noex, TREE_PURPOSE (add)));
kono
parents:
diff changeset
2510
kono
parents:
diff changeset
2511 /* Combine the dynamic-exception-specifiers, if any. */
kono
parents:
diff changeset
2512 orig_list = list;
kono
parents:
diff changeset
2513 for (; add && TREE_VALUE (add); add = TREE_CHAIN (add))
kono
parents:
diff changeset
2514 {
kono
parents:
diff changeset
2515 tree spec = TREE_VALUE (add);
kono
parents:
diff changeset
2516 tree probe;
kono
parents:
diff changeset
2517
kono
parents:
diff changeset
2518 for (probe = orig_list; probe && TREE_VALUE (probe);
kono
parents:
diff changeset
2519 probe = TREE_CHAIN (probe))
kono
parents:
diff changeset
2520 if (same_type_p (TREE_VALUE (probe), spec))
kono
parents:
diff changeset
2521 break;
kono
parents:
diff changeset
2522 if (!probe)
kono
parents:
diff changeset
2523 {
kono
parents:
diff changeset
2524 spec = build_tree_list (NULL_TREE, spec);
kono
parents:
diff changeset
2525 TREE_CHAIN (spec) = list;
kono
parents:
diff changeset
2526 list = spec;
kono
parents:
diff changeset
2527 }
kono
parents:
diff changeset
2528 }
kono
parents:
diff changeset
2529
kono
parents:
diff changeset
2530 /* Keep the noexcept-specifier at the beginning of the list. */
kono
parents:
diff changeset
2531 if (noex != TREE_PURPOSE (list))
kono
parents:
diff changeset
2532 list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list));
kono
parents:
diff changeset
2533
kono
parents:
diff changeset
2534 return list;
kono
parents:
diff changeset
2535 }
kono
parents:
diff changeset
2536
kono
parents:
diff changeset
2537 /* Subroutine of build_call. Ensure that each of the types in the
kono
parents:
diff changeset
2538 exception specification is complete. Technically, 15.4/1 says that
kono
parents:
diff changeset
2539 they need to be complete when we see a declaration of the function,
kono
parents:
diff changeset
2540 but we should be able to get away with only requiring this when the
kono
parents:
diff changeset
2541 function is defined or called. See also add_exception_specifier. */
kono
parents:
diff changeset
2542
kono
parents:
diff changeset
2543 void
kono
parents:
diff changeset
2544 require_complete_eh_spec_types (tree fntype, tree decl)
kono
parents:
diff changeset
2545 {
kono
parents:
diff changeset
2546 tree raises;
kono
parents:
diff changeset
2547 /* Don't complain about calls to op new. */
kono
parents:
diff changeset
2548 if (decl && DECL_ARTIFICIAL (decl))
kono
parents:
diff changeset
2549 return;
kono
parents:
diff changeset
2550 for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises;
kono
parents:
diff changeset
2551 raises = TREE_CHAIN (raises))
kono
parents:
diff changeset
2552 {
kono
parents:
diff changeset
2553 tree type = TREE_VALUE (raises);
kono
parents:
diff changeset
2554 if (type && !COMPLETE_TYPE_P (type))
kono
parents:
diff changeset
2555 {
kono
parents:
diff changeset
2556 if (decl)
kono
parents:
diff changeset
2557 error
kono
parents:
diff changeset
2558 ("call to function %qD which throws incomplete type %q#T",
kono
parents:
diff changeset
2559 decl, type);
kono
parents:
diff changeset
2560 else
kono
parents:
diff changeset
2561 error ("call to function which throws incomplete type %q#T",
kono
parents:
diff changeset
2562 decl);
kono
parents:
diff changeset
2563 }
kono
parents:
diff changeset
2564 }
kono
parents:
diff changeset
2565 }
kono
parents:
diff changeset
2566
kono
parents:
diff changeset
2567
kono
parents:
diff changeset
2568 #include "gt-cp-typeck2.h"