annotate gcc/cp/typeck2.c @ 143:76e1cf5455ef

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