]>
Commit | Line | Data |
---|---|---|
471086d6 | 1 | /* Handle the hair of processing (but not expanding) inline functions. |
2 | Also manage function and variable name overloading. | |
f1717362 | 3 | Copyright (C) 1987-2016 Free Software Foundation, Inc. |
471086d6 | 4 | Contributed by Michael Tiemann (tiemann@cygnus.com) |
5 | ||
6f0d25a6 | 6 | This file is part of GCC. |
9031d10b | 7 | |
6f0d25a6 | 8 | GCC is free software; you can redistribute it and/or modify |
471086d6 | 9 | it under the terms of the GNU General Public License as published by |
aa139c3f | 10 | the Free Software Foundation; either version 3, or (at your option) |
471086d6 | 11 | any later version. |
12 | ||
6f0d25a6 | 13 | GCC is distributed in the hope that it will be useful, |
471086d6 | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
aa139c3f | 19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
471086d6 | 21 | |
22 | ||
471086d6 | 23 | /* Handle method declarations. */ |
471086d6 | 24 | #include "config.h" |
69af4bcc | 25 | #include "system.h" |
805e22b2 | 26 | #include "coretypes.h" |
4cba6f60 | 27 | #include "target.h" |
4cba6f60 | 28 | #include "cp-tree.h" |
9ed99284 | 29 | #include "stringpool.h" |
4cba6f60 | 30 | #include "cgraph.h" |
9ed99284 | 31 | #include "varasm.h" |
2a4e40b0 | 32 | #include "toplev.h" |
218e3e4e | 33 | #include "common/common-target.h" |
471086d6 | 34 | |
442fd60a | 35 | /* Various flags to control the mangling process. */ |
36 | ||
37 | enum mangling_flags | |
38 | { | |
39 | /* No flags. */ | |
40 | mf_none = 0, | |
41 | /* The thing we are presently mangling is part of a template type, | |
42 | rather than a fully instantiated type. Therefore, we may see | |
43 | complex expressions where we would normally expect to see a | |
44 | simple integer constant. */ | |
45 | mf_maybe_uninstantiated = 1, | |
46 | /* When mangling a numeric value, use the form `_XX_' (instead of | |
47 | just `XX') if the value has more than one digit. */ | |
4fa0b096 | 48 | mf_use_underscores_around_value = 2 |
442fd60a | 49 | }; |
50 | ||
ab8002de | 51 | static void do_build_copy_assign (tree); |
805e22b2 | 52 | static void do_build_copy_constructor (tree); |
fee08769 | 53 | static tree make_alias_for_thunk (tree); |
442fd60a | 54 | |
442fd60a | 55 | /* Called once to initialize method.c. */ |
56 | ||
57 | void | |
805e22b2 | 58 | init_method (void) |
442fd60a | 59 | { |
606b494c | 60 | init_mangle (); |
442fd60a | 61 | } |
0543e7a9 | 62 | \f |
805e22b2 | 63 | /* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING |
64 | indicates whether it is a this or result adjusting thunk. | |
65 | FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment | |
66 | (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET | |
67 | never is. VIRTUAL_OFFSET is the /index/ into the vtable for this | |
68 | adjusting thunks, we scale it to a byte offset. For covariant | |
69 | thunks VIRTUAL_OFFSET is the virtual binfo. You must post process | |
70 | the returned thunk with finish_thunk. */ | |
98eaf693 | 71 | |
0543e7a9 | 72 | tree |
805e22b2 | 73 | make_thunk (tree function, bool this_adjusting, |
74 | tree fixed_offset, tree virtual_offset) | |
0543e7a9 | 75 | { |
2b82dde2 | 76 | HOST_WIDE_INT d; |
805e22b2 | 77 | tree thunk; |
9031d10b | 78 | |
b4df430b | 79 | gcc_assert (TREE_CODE (function) == FUNCTION_DECL); |
6beb3f76 | 80 | /* We can have this thunks to covariant thunks, but not vice versa. */ |
b4df430b | 81 | gcc_assert (!DECL_THIS_THUNK_P (function)); |
82 | gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting); | |
9031d10b | 83 | |
805e22b2 | 84 | /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */ |
85 | if (this_adjusting && virtual_offset) | |
9031d10b | 86 | virtual_offset |
2b82dde2 | 87 | = size_binop (MULT_EXPR, |
653e5405 | 88 | virtual_offset, |
89 | convert (ssizetype, | |
90 | TYPE_SIZE_UNIT (vtable_entry_type))); | |
9031d10b | 91 | |
fcb97e84 | 92 | d = tree_to_shwi (fixed_offset); |
9031d10b | 93 | |
805e22b2 | 94 | /* See if we already have the thunk in question. For this_adjusting |
95 | thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it | |
6beb3f76 | 96 | will be a BINFO. */ |
1767a056 | 97 | for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk)) |
6709b660 | 98 | if (DECL_THIS_THUNK_P (thunk) == this_adjusting |
99 | && THUNK_FIXED_OFFSET (thunk) == d | |
100 | && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk) | |
101 | && (!virtual_offset | |
102 | || (this_adjusting | |
103 | ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk), | |
104 | virtual_offset) | |
105 | : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset))) | |
106 | return thunk; | |
9031d10b | 107 | |
641985fa | 108 | /* All thunks must be created before FUNCTION is actually emitted; |
109 | the ABI requires that all thunks be emitted together with the | |
110 | function to which they transfer control. */ | |
b4df430b | 111 | gcc_assert (!TREE_ASM_WRITTEN (function)); |
1aed9396 | 112 | /* Likewise, we can only be adding thunks to a function declared in |
113 | the class currently being laid out. */ | |
b4df430b | 114 | gcc_assert (TYPE_SIZE (DECL_CONTEXT (function)) |
115 | && TYPE_BEING_DEFINED (DECL_CONTEXT (function))); | |
641985fa | 116 | |
e60a6f7b | 117 | thunk = build_decl (DECL_SOURCE_LOCATION (function), |
118 | FUNCTION_DECL, NULL_TREE, TREE_TYPE (function)); | |
641985fa | 119 | DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function); |
71b1859a | 120 | cxx_dup_lang_specific_decl (thunk); |
f959fce9 | 121 | DECL_VIRTUAL_P (thunk) = true; |
122 | SET_DECL_THUNKS (thunk, NULL_TREE); | |
9031d10b | 123 | |
641985fa | 124 | DECL_CONTEXT (thunk) = DECL_CONTEXT (function); |
125 | TREE_READONLY (thunk) = TREE_READONLY (function); | |
126 | TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function); | |
127 | TREE_PUBLIC (thunk) = TREE_PUBLIC (function); | |
805e22b2 | 128 | SET_DECL_THUNK_P (thunk, this_adjusting); |
71b1859a | 129 | THUNK_TARGET (thunk) = function; |
130 | THUNK_FIXED_OFFSET (thunk) = d; | |
805e22b2 | 131 | THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset; |
6709b660 | 132 | THUNK_ALIAS (thunk) = NULL_TREE; |
9031d10b | 133 | |
641985fa | 134 | DECL_INTERFACE_KNOWN (thunk) = 1; |
135 | DECL_NOT_REALLY_EXTERN (thunk) = 1; | |
38063122 | 136 | DECL_COMDAT (thunk) = DECL_COMDAT (function); |
641985fa | 137 | DECL_SAVED_FUNCTION_DATA (thunk) = NULL; |
38063122 | 138 | /* The thunk itself is not a constructor or destructor, even if |
139 | the thing it is thunking to is. */ | |
641985fa | 140 | DECL_DESTRUCTOR_P (thunk) = 0; |
141 | DECL_CONSTRUCTOR_P (thunk) = 0; | |
641985fa | 142 | DECL_EXTERNAL (thunk) = 1; |
143 | DECL_ARTIFICIAL (thunk) = 1; | |
641985fa | 144 | /* The THUNK is not a pending inline, even if the FUNCTION is. */ |
145 | DECL_PENDING_INLINE_P (thunk) = 0; | |
2df45762 | 146 | DECL_DECLARED_INLINE_P (thunk) = 0; |
afe02847 | 147 | /* Nor is it a template instantiation. */ |
148 | DECL_USE_TEMPLATE (thunk) = 0; | |
149 | DECL_TEMPLATE_INFO (thunk) = NULL; | |
9031d10b | 150 | |
641985fa | 151 | /* Add it to the list of thunks associated with FUNCTION. */ |
1767a056 | 152 | DECL_CHAIN (thunk) = DECL_THUNKS (function); |
f959fce9 | 153 | SET_DECL_THUNKS (function, thunk); |
a1d45d09 | 154 | |
0543e7a9 | 155 | return thunk; |
156 | } | |
157 | ||
71b1859a | 158 | /* Finish THUNK, a thunk decl. */ |
f85d646a | 159 | |
0543e7a9 | 160 | void |
71b1859a | 161 | finish_thunk (tree thunk) |
805e22b2 | 162 | { |
163 | tree function, name; | |
85390276 | 164 | tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk)); |
71b1859a | 165 | tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk); |
166 | ||
b4df430b | 167 | gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk)); |
71b1859a | 168 | if (virtual_offset && DECL_RESULT_THUNK_P (thunk)) |
169 | virtual_offset = BINFO_VPTR_FIELD (virtual_offset); | |
170 | function = THUNK_TARGET (thunk); | |
805e22b2 | 171 | name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk), |
71b1859a | 172 | fixed_offset, virtual_offset); |
4880ab99 | 173 | |
174 | /* We can end up with declarations of (logically) different | |
175 | covariant thunks, that do identical adjustments. The two thunks | |
176 | will be adjusting between within different hierarchies, which | |
177 | happen to have the same layout. We must nullify one of them to | |
178 | refer to the other. */ | |
179 | if (DECL_RESULT_THUNK_P (thunk)) | |
180 | { | |
181 | tree cov_probe; | |
182 | ||
183 | for (cov_probe = DECL_THUNKS (function); | |
1767a056 | 184 | cov_probe; cov_probe = DECL_CHAIN (cov_probe)) |
4880ab99 | 185 | if (DECL_NAME (cov_probe) == name) |
186 | { | |
b4df430b | 187 | gcc_assert (!DECL_THUNKS (thunk)); |
6709b660 | 188 | THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe) |
4880ab99 | 189 | ? THUNK_ALIAS (cov_probe) : cov_probe); |
190 | break; | |
191 | } | |
192 | } | |
9031d10b | 193 | |
805e22b2 | 194 | DECL_NAME (thunk) = name; |
195 | SET_DECL_ASSEMBLER_NAME (thunk, name); | |
196 | } | |
197 | ||
d7bec695 | 198 | static GTY (()) int thunk_labelno; |
199 | ||
1b155d83 | 200 | /* Create a static alias to target. */ |
d7bec695 | 201 | |
dc5e5216 | 202 | tree |
1b155d83 | 203 | make_alias_for (tree target, tree newid) |
d7bec695 | 204 | { |
1b155d83 | 205 | tree alias = build_decl (DECL_SOURCE_LOCATION (target), |
206 | TREE_CODE (target), newid, TREE_TYPE (target)); | |
207 | DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target); | |
d7bec695 | 208 | cxx_dup_lang_specific_decl (alias); |
209 | DECL_CONTEXT (alias) = NULL; | |
1b155d83 | 210 | TREE_READONLY (alias) = TREE_READONLY (target); |
211 | TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target); | |
d7bec695 | 212 | TREE_PUBLIC (alias) = 0; |
213 | DECL_INTERFACE_KNOWN (alias) = 1; | |
d6c998f4 | 214 | if (DECL_LANG_SPECIFIC (alias)) |
215 | { | |
216 | DECL_NOT_REALLY_EXTERN (alias) = 1; | |
217 | DECL_USE_TEMPLATE (alias) = 0; | |
218 | DECL_TEMPLATE_INFO (alias) = NULL; | |
219 | } | |
d7bec695 | 220 | DECL_EXTERNAL (alias) = 0; |
221 | DECL_ARTIFICIAL (alias) = 1; | |
d7bec695 | 222 | DECL_TEMPLATE_INSTANTIATED (alias) = 0; |
1b155d83 | 223 | if (TREE_CODE (alias) == FUNCTION_DECL) |
224 | { | |
225 | DECL_SAVED_FUNCTION_DATA (alias) = NULL; | |
226 | DECL_DESTRUCTOR_P (alias) = 0; | |
227 | DECL_CONSTRUCTOR_P (alias) = 0; | |
228 | DECL_PENDING_INLINE_P (alias) = 0; | |
229 | DECL_DECLARED_INLINE_P (alias) = 0; | |
230 | DECL_INITIAL (alias) = error_mark_node; | |
231 | DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target)); | |
232 | } | |
233 | else | |
234 | TREE_STATIC (alias) = 1; | |
d7bec695 | 235 | TREE_ADDRESSABLE (alias) = 1; |
236 | TREE_USED (alias) = 1; | |
237 | SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias)); | |
dc5e5216 | 238 | return alias; |
239 | } | |
240 | ||
241 | static tree | |
242 | make_alias_for_thunk (tree function) | |
243 | { | |
244 | tree alias; | |
245 | char buf[256]; | |
246 | ||
cb274b8f | 247 | targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno); |
dc5e5216 | 248 | thunk_labelno++; |
249 | ||
250 | alias = make_alias_for (function, get_identifier (buf)); | |
251 | ||
d7bec695 | 252 | if (!flag_syntax_only) |
28454517 | 253 | { |
9a9dbef1 | 254 | struct cgraph_node *funcn, *aliasn; |
415d1b9a | 255 | funcn = cgraph_node::get (function); |
9a9dbef1 | 256 | gcc_checking_assert (funcn); |
415d1b9a | 257 | aliasn = cgraph_node::create_same_body_alias (alias, function); |
28454517 | 258 | DECL_ASSEMBLER_NAME (function); |
9ced88d0 | 259 | gcc_assert (aliasn != NULL); |
28454517 | 260 | } |
dc5e5216 | 261 | |
d7bec695 | 262 | return alias; |
263 | } | |
264 | ||
805e22b2 | 265 | /* Emit the definition of a C++ multiple inheritance or covariant |
266 | return vtable thunk. If EMIT_P is nonzero, the thunk is emitted | |
267 | immediately. */ | |
268 | ||
269 | void | |
270 | use_thunk (tree thunk_fndecl, bool emit_p) | |
0543e7a9 | 271 | { |
043dbdf4 | 272 | tree a, t, function, alias; |
805e22b2 | 273 | tree virtual_offset; |
274 | HOST_WIDE_INT fixed_offset, virtual_value; | |
71b1859a | 275 | bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl); |
dabebf7e | 276 | struct cgraph_node *funcn, *thunk_node; |
805e22b2 | 277 | |
6beb3f76 | 278 | /* We should have called finish_thunk to give it a name. */ |
b4df430b | 279 | gcc_assert (DECL_NAME (thunk_fndecl)); |
0543e7a9 | 280 | |
4880ab99 | 281 | /* We should never be using an alias, always refer to the |
282 | aliased thunk. */ | |
b4df430b | 283 | gcc_assert (!THUNK_ALIAS (thunk_fndecl)); |
4880ab99 | 284 | |
0543e7a9 | 285 | if (TREE_ASM_WRITTEN (thunk_fndecl)) |
286 | return; | |
9031d10b | 287 | |
71b1859a | 288 | function = THUNK_TARGET (thunk_fndecl); |
289 | if (DECL_RESULT (thunk_fndecl)) | |
759113c3 | 290 | /* We already turned this thunk into an ordinary function. |
a97cce53 | 291 | There's no need to process this thunk again. */ |
759113c3 | 292 | return; |
293 | ||
f05abcd9 | 294 | if (DECL_THUNK_P (function)) |
295 | /* The target is itself a thunk, process it now. */ | |
296 | use_thunk (function, emit_p); | |
9031d10b | 297 | |
2b82dde2 | 298 | /* Thunks are always addressable; they only appear in vtables. */ |
299 | TREE_ADDRESSABLE (thunk_fndecl) = 1; | |
ddb9bca7 | 300 | |
2b82dde2 | 301 | /* Figure out what function is being thunked to. It's referenced in |
302 | this translation unit. */ | |
cc52ae6a | 303 | TREE_ADDRESSABLE (function) = 1; |
304 | mark_used (function); | |
2b82dde2 | 305 | if (!emit_p) |
306 | return; | |
cc52ae6a | 307 | |
5c0b8490 | 308 | if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)) |
309 | alias = make_alias_for_thunk (function); | |
310 | else | |
311 | alias = function; | |
d7bec695 | 312 | |
805e22b2 | 313 | fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl); |
314 | virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl); | |
eb344f43 | 315 | |
71b1859a | 316 | if (virtual_offset) |
317 | { | |
318 | if (!this_adjusting) | |
319 | virtual_offset = BINFO_VPTR_FIELD (virtual_offset); | |
fcb97e84 | 320 | virtual_value = tree_to_shwi (virtual_offset); |
b4df430b | 321 | gcc_assert (virtual_value); |
71b1859a | 322 | } |
323 | else | |
324 | virtual_value = 0; | |
9031d10b | 325 | |
2b82dde2 | 326 | /* And, if we need to emit the thunk, it's used. */ |
327 | mark_used (thunk_fndecl); | |
328 | /* This thunk is actually defined. */ | |
329 | DECL_EXTERNAL (thunk_fndecl) = 0; | |
9a899b25 | 330 | /* The linkage of the function may have changed. FIXME in linkage |
331 | rewrite. */ | |
04b0e01b | 332 | gcc_assert (DECL_INTERFACE_KNOWN (function)); |
9a899b25 | 333 | TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function); |
9c40570a | 334 | DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function); |
9031d10b | 335 | DECL_VISIBILITY_SPECIFIED (thunk_fndecl) |
91caa6ca | 336 | = DECL_VISIBILITY_SPECIFIED (function); |
38063122 | 337 | DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function); |
dabebf7e | 338 | DECL_WEAK (thunk_fndecl) = DECL_WEAK (function); |
22f1c933 | 339 | |
759113c3 | 340 | if (flag_syntax_only) |
341 | { | |
342 | TREE_ASM_WRITTEN (thunk_fndecl) = 1; | |
343 | return; | |
344 | } | |
345 | ||
2b82dde2 | 346 | push_to_top_level (); |
347 | ||
5c0b8490 | 348 | if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function) |
218e3e4e | 349 | && targetm_common.have_named_sections) |
d7bec695 | 350 | { |
e4c07a06 | 351 | tree fn = function; |
352 | struct symtab_node *symbol; | |
d7bec695 | 353 | |
415d1b9a | 354 | if ((symbol = symtab_node::get (function)) |
e4c07a06 | 355 | && symbol->alias) |
356 | { | |
357 | if (symbol->analyzed) | |
415d1b9a | 358 | fn = symtab_node::get (function)->ultimate_alias_target ()->decl; |
e4c07a06 | 359 | else |
415d1b9a | 360 | fn = symtab_node::get (function)->alias_target; |
e4c07a06 | 361 | } |
362 | resolve_unique_section (fn, 0, flag_function_sections); | |
363 | ||
364 | if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn)) | |
d7bec695 | 365 | { |
366 | resolve_unique_section (thunk_fndecl, 0, flag_function_sections); | |
367 | ||
368 | /* Output the thunk into the same section as function. */ | |
e4c07a06 | 369 | set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (fn)); |
415d1b9a | 370 | symtab_node::get (thunk_fndecl)->implicit_section |
371 | = symtab_node::get (fn)->implicit_section; | |
d7bec695 | 372 | } |
373 | } | |
d7bec695 | 374 | |
043dbdf4 | 375 | /* Set up cloned argument trees for the thunk. */ |
376 | t = NULL_TREE; | |
1767a056 | 377 | for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a)) |
043dbdf4 | 378 | { |
379 | tree x = copy_node (a); | |
1767a056 | 380 | DECL_CHAIN (x) = t; |
043dbdf4 | 381 | DECL_CONTEXT (x) = thunk_fndecl; |
c4b9c21a | 382 | SET_DECL_RTL (x, NULL); |
1182c12e | 383 | DECL_HAS_VALUE_EXPR_P (x) = 0; |
32578a98 | 384 | TREE_ADDRESSABLE (x) = 0; |
043dbdf4 | 385 | t = x; |
386 | } | |
387 | a = nreverse (t); | |
388 | DECL_ARGUMENTS (thunk_fndecl) = a; | |
28454517 | 389 | TREE_ASM_WRITTEN (thunk_fndecl) = 1; |
415d1b9a | 390 | funcn = cgraph_node::get (function); |
9a9dbef1 | 391 | gcc_checking_assert (funcn); |
415d1b9a | 392 | thunk_node = funcn->create_thunk (thunk_fndecl, function, |
393 | this_adjusting, fixed_offset, virtual_value, | |
394 | virtual_offset, alias); | |
dabebf7e | 395 | if (DECL_ONE_ONLY (function)) |
415d1b9a | 396 | thunk_node->add_to_same_comdat_group (funcn); |
28454517 | 397 | |
2b82dde2 | 398 | pop_from_top_level (); |
0543e7a9 | 399 | } |
c38086bd | 400 | \f |
401 | /* Code for synthesizing methods which have default semantics defined. */ | |
402 | ||
2ee92e27 | 403 | /* True iff CTYPE has a trivial SFK. */ |
404 | ||
405 | static bool | |
406 | type_has_trivial_fn (tree ctype, special_function_kind sfk) | |
407 | { | |
408 | switch (sfk) | |
409 | { | |
410 | case sfk_constructor: | |
411 | return !TYPE_HAS_COMPLEX_DFLT (ctype); | |
412 | case sfk_copy_constructor: | |
413 | return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype); | |
414 | case sfk_move_constructor: | |
415 | return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype); | |
416 | case sfk_copy_assignment: | |
417 | return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype); | |
418 | case sfk_move_assignment: | |
419 | return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype); | |
420 | case sfk_destructor: | |
421 | return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype); | |
fa6e8832 | 422 | case sfk_inheriting_constructor: |
423 | return false; | |
2ee92e27 | 424 | default: |
425 | gcc_unreachable (); | |
426 | } | |
427 | } | |
428 | ||
429 | /* Note that CTYPE has a non-trivial SFK even though we previously thought | |
430 | it was trivial. */ | |
431 | ||
432 | static void | |
433 | type_set_nontrivial_flag (tree ctype, special_function_kind sfk) | |
434 | { | |
435 | switch (sfk) | |
436 | { | |
437 | case sfk_constructor: | |
438 | TYPE_HAS_COMPLEX_DFLT (ctype) = true; | |
439 | return; | |
440 | case sfk_copy_constructor: | |
441 | TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true; | |
442 | return; | |
443 | case sfk_move_constructor: | |
444 | TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true; | |
445 | return; | |
446 | case sfk_copy_assignment: | |
447 | TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true; | |
448 | return; | |
449 | case sfk_move_assignment: | |
450 | TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true; | |
451 | return; | |
452 | case sfk_destructor: | |
453 | TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true; | |
454 | return; | |
fa6e8832 | 455 | case sfk_inheriting_constructor: |
2ee92e27 | 456 | default: |
457 | gcc_unreachable (); | |
458 | } | |
459 | } | |
460 | ||
461 | /* True iff FN is a trivial defaulted member function ([cd]tor, op=). */ | |
462 | ||
463 | bool | |
464 | trivial_fn_p (tree fn) | |
465 | { | |
23d64a17 | 466 | if (TREE_CODE (fn) == TEMPLATE_DECL) |
467 | return false; | |
2ee92e27 | 468 | if (!DECL_DEFAULTED_FN (fn)) |
469 | return false; | |
470 | ||
471 | /* If fn is a clone, get the primary variant. */ | |
468088ac | 472 | if (tree prim = DECL_CLONED_FUNCTION (fn)) |
473 | fn = prim; | |
2ee92e27 | 474 | return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn)); |
475 | } | |
476 | ||
fa6e8832 | 477 | /* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO |
478 | given the parameter or parameters PARM, possibly inherited constructor | |
479 | base INH, or move flag MOVE_P. */ | |
480 | ||
481 | static tree | |
482 | add_one_base_init (tree binfo, tree parm, bool move_p, tree inh, | |
483 | tree member_init_list) | |
484 | { | |
485 | tree init; | |
486 | if (inh) | |
487 | { | |
488 | /* An inheriting constructor only has a mem-initializer for | |
489 | the base it inherits from. */ | |
490 | if (BINFO_TYPE (binfo) != inh) | |
491 | return member_init_list; | |
492 | ||
493 | tree *p = &init; | |
494 | init = NULL_TREE; | |
495 | for (; parm; parm = DECL_CHAIN (parm)) | |
496 | { | |
497 | tree exp = convert_from_reference (parm); | |
65e921ca | 498 | if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE |
499 | || TYPE_REF_IS_RVALUE (TREE_TYPE (parm))) | |
fa6e8832 | 500 | exp = move (exp); |
501 | *p = build_tree_list (NULL_TREE, exp); | |
502 | p = &TREE_CHAIN (*p); | |
503 | } | |
504 | } | |
505 | else | |
506 | { | |
507 | init = build_base_path (PLUS_EXPR, parm, binfo, 1, | |
508 | tf_warning_or_error); | |
509 | if (move_p) | |
510 | init = move (init); | |
511 | init = build_tree_list (NULL_TREE, init); | |
512 | } | |
513 | return tree_cons (binfo, init, member_init_list); | |
514 | } | |
515 | ||
516 | /* Generate code for default X(X&) or X(X&&) constructor or an inheriting | |
517 | constructor. */ | |
96624a9e | 518 | |
02d7f858 | 519 | static void |
805e22b2 | 520 | do_build_copy_constructor (tree fndecl) |
c38086bd | 521 | { |
dcbeb3ef | 522 | tree parm = FUNCTION_FIRST_USER_PARM (fndecl); |
a8b75081 | 523 | bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl); |
2ee92e27 | 524 | bool trivial = trivial_fn_p (fndecl); |
fa6e8832 | 525 | tree inh = DECL_INHERITED_CTOR_BASE (fndecl); |
c38086bd | 526 | |
fa6e8832 | 527 | if (!inh) |
528 | parm = convert_from_reference (parm); | |
c38086bd | 529 | |
2ee92e27 | 530 | if (trivial |
2af98c0d | 531 | && is_empty_class (current_class_type)) |
532 | /* Don't copy the padding byte; it might not have been allocated | |
533 | if *this is a base subobject. */; | |
2ee92e27 | 534 | else if (trivial) |
c38086bd | 535 | { |
7880033a | 536 | tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); |
b48733fd | 537 | finish_expr_stmt (t); |
c38086bd | 538 | } |
539 | else | |
540 | { | |
541 | tree fields = TYPE_FIELDS (current_class_type); | |
bc577f39 | 542 | tree member_init_list = NULL_TREE; |
3119c950 | 543 | int cvquals = cp_type_quals (TREE_TYPE (parm)); |
c38086bd | 544 | int i; |
f6cc6a08 | 545 | tree binfo, base_binfo; |
a8b75081 | 546 | tree init; |
f1f41a6c | 547 | vec<tree, va_gc> *vbases; |
c38086bd | 548 | |
e928040e | 549 | /* Initialize all the base-classes with the parameter converted |
550 | to their type so that we get their copy constructor and not | |
551 | another constructor that takes current_class_type. We must | |
552 | deal with the binfo's directly as a direct base might be | |
553 | inaccessible due to ambiguity. */ | |
930bdacf | 554 | for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0; |
f1f41a6c | 555 | vec_safe_iterate (vbases, i, &binfo); i++) |
dbacd3bd | 556 | { |
fa6e8832 | 557 | member_init_list = add_one_base_init (binfo, parm, move_p, inh, |
558 | member_init_list); | |
dbacd3bd | 559 | } |
560 | ||
f6cc6a08 | 561 | for (binfo = TYPE_BINFO (current_class_type), i = 0; |
562 | BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | |
c38086bd | 563 | { |
f6cc6a08 | 564 | if (BINFO_VIRTUAL_P (base_binfo)) |
9031d10b | 565 | continue; |
fa6e8832 | 566 | member_init_list = add_one_base_init (base_binfo, parm, move_p, |
567 | inh, member_init_list); | |
c38086bd | 568 | } |
3cb03149 | 569 | |
1767a056 | 570 | for (; fields; fields = DECL_CHAIN (fields)) |
c38086bd | 571 | { |
127a1cd0 | 572 | tree field = fields; |
9c6e252e | 573 | tree expr_type; |
127a1cd0 | 574 | |
575 | if (TREE_CODE (field) != FIELD_DECL) | |
c38086bd | 576 | continue; |
fa6e8832 | 577 | if (inh) |
578 | continue; | |
003da05e | 579 | |
7880033a | 580 | expr_type = TREE_TYPE (field); |
127a1cd0 | 581 | if (DECL_NAME (field)) |
c38086bd | 582 | { |
127a1cd0 | 583 | if (VFIELD_NAME_P (DECL_NAME (field))) |
c38086bd | 584 | continue; |
c38086bd | 585 | } |
7880033a | 586 | else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) |
128e1d72 | 587 | /* Just use the field; anonymous types can't have |
80e54732 | 588 | nontrivial copy ctors or assignment ops or this |
589 | function would be deleted. */; | |
48a6ce0d | 590 | else |
591 | continue; | |
c38086bd | 592 | |
9c6e252e | 593 | /* Compute the type of "init->field". If the copy-constructor |
594 | parameter is, for example, "const S&", and the type of | |
595 | the field is "T", then the type will usually be "const | |
596 | T". (There are no cv-qualified variants of reference | |
597 | types.) */ | |
9c6e252e | 598 | if (TREE_CODE (expr_type) != REFERENCE_TYPE) |
7880033a | 599 | { |
600 | int quals = cvquals; | |
9031d10b | 601 | |
7880033a | 602 | if (DECL_MUTABLE_P (field)) |
603 | quals &= ~TYPE_QUAL_CONST; | |
ce494fcf | 604 | quals |= cp_type_quals (expr_type); |
7880033a | 605 | expr_type = cp_build_qualified_type (expr_type, quals); |
606 | } | |
9031d10b | 607 | |
a8b75081 | 608 | init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE); |
71ee51f6 | 609 | if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE |
610 | /* 'move' breaks bit-fields, and has no effect for scalars. */ | |
611 | && !scalarish_type_p (expr_type)) | |
a8b75081 | 612 | init = move (init); |
c38086bd | 613 | init = build_tree_list (NULL_TREE, init); |
614 | ||
7880033a | 615 | member_init_list = tree_cons (field, init, member_init_list); |
c38086bd | 616 | } |
6507cda8 | 617 | finish_mem_initializers (member_init_list); |
c38086bd | 618 | } |
c38086bd | 619 | } |
620 | ||
02d7f858 | 621 | static void |
ab8002de | 622 | do_build_copy_assign (tree fndecl) |
c38086bd | 623 | { |
1767a056 | 624 | tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl)); |
b48733fd | 625 | tree compound_stmt; |
2ee92e27 | 626 | bool move_p = move_fn_p (fndecl); |
627 | bool trivial = trivial_fn_p (fndecl); | |
ed2deec6 | 628 | int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED; |
c38086bd | 629 | |
2363ef00 | 630 | compound_stmt = begin_compound_stmt (0); |
c38086bd | 631 | parm = convert_from_reference (parm); |
632 | ||
2ee92e27 | 633 | if (trivial |
2af98c0d | 634 | && is_empty_class (current_class_type)) |
635 | /* Don't copy the padding byte; it might not have been allocated | |
636 | if *this is a base subobject. */; | |
2ee92e27 | 637 | else if (trivial) |
c38086bd | 638 | { |
831d52a2 | 639 | tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm); |
b48733fd | 640 | finish_expr_stmt (t); |
c38086bd | 641 | } |
642 | else | |
643 | { | |
f70cb9e6 | 644 | tree fields; |
3119c950 | 645 | int cvquals = cp_type_quals (TREE_TYPE (parm)); |
c38086bd | 646 | int i; |
f6cc6a08 | 647 | tree binfo, base_binfo; |
c38086bd | 648 | |
c1c5bfe2 | 649 | /* Assign to each of the direct base classes. */ |
f6cc6a08 | 650 | for (binfo = TYPE_BINFO (current_class_type), i = 0; |
651 | BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | |
c38086bd | 652 | { |
f70cb9e6 | 653 | tree converted_parm; |
f1f41a6c | 654 | vec<tree, va_gc> *parmvec; |
f70cb9e6 | 655 | |
f70cb9e6 | 656 | /* We must convert PARM directly to the base class |
657 | explicitly since the base class may be ambiguous. */ | |
1e74225a | 658 | converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1, |
659 | tf_warning_or_error); | |
2ee92e27 | 660 | if (move_p) |
661 | converted_parm = move (converted_parm); | |
f70cb9e6 | 662 | /* Call the base class assignment operator. */ |
f352a3fb | 663 | parmvec = make_tree_vector_single (converted_parm); |
9031d10b | 664 | finish_expr_stmt |
665 | (build_special_member_call (current_class_ref, | |
f70cb9e6 | 666 | ansi_assopname (NOP_EXPR), |
f352a3fb | 667 | &parmvec, |
f6cc6a08 | 668 | base_binfo, |
ed2deec6 | 669 | flags, |
ebd21de4 | 670 | tf_warning_or_error)); |
f352a3fb | 671 | release_tree_vector (parmvec); |
c38086bd | 672 | } |
f70cb9e6 | 673 | |
674 | /* Assign to each of the non-static data members. */ | |
9031d10b | 675 | for (fields = TYPE_FIELDS (current_class_type); |
676 | fields; | |
1767a056 | 677 | fields = DECL_CHAIN (fields)) |
c38086bd | 678 | { |
7880033a | 679 | tree comp = current_class_ref; |
680 | tree init = parm; | |
127a1cd0 | 681 | tree field = fields; |
7880033a | 682 | tree expr_type; |
683 | int quals; | |
127a1cd0 | 684 | |
23ed74d8 | 685 | if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) |
c38086bd | 686 | continue; |
1ad432f2 | 687 | |
7880033a | 688 | expr_type = TREE_TYPE (field); |
9031d10b | 689 | |
7880033a | 690 | if (CP_TYPE_CONST_P (expr_type)) |
1ad432f2 | 691 | { |
bf776685 | 692 | error ("non-static const member %q#D, can%'t use default " |
653e5405 | 693 | "assignment operator", field); |
1ad432f2 | 694 | continue; |
695 | } | |
7880033a | 696 | else if (TREE_CODE (expr_type) == REFERENCE_TYPE) |
1ad432f2 | 697 | { |
bf776685 | 698 | error ("non-static reference member %q#D, can%'t use " |
653e5405 | 699 | "default assignment operator", field); |
1ad432f2 | 700 | continue; |
701 | } | |
702 | ||
127a1cd0 | 703 | if (DECL_NAME (field)) |
c38086bd | 704 | { |
127a1cd0 | 705 | if (VFIELD_NAME_P (DECL_NAME (field))) |
c38086bd | 706 | continue; |
c38086bd | 707 | } |
7880033a | 708 | else if (ANON_AGGR_TYPE_P (expr_type) |
709 | && TYPE_FIELDS (expr_type) != NULL_TREE) | |
128e1d72 | 710 | /* Just use the field; anonymous types can't have |
80e54732 | 711 | nontrivial copy ctors or assignment ops or this |
712 | function would be deleted. */; | |
48a6ce0d | 713 | else |
714 | continue; | |
c38086bd | 715 | |
7880033a | 716 | comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE); |
9031d10b | 717 | |
7880033a | 718 | /* Compute the type of init->field */ |
719 | quals = cvquals; | |
720 | if (DECL_MUTABLE_P (field)) | |
721 | quals &= ~TYPE_QUAL_CONST; | |
722 | expr_type = cp_build_qualified_type (expr_type, quals); | |
9031d10b | 723 | |
7880033a | 724 | init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); |
71ee51f6 | 725 | if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE |
726 | /* 'move' breaks bit-fields, and has no effect for scalars. */ | |
727 | && !scalarish_type_p (expr_type)) | |
2ee92e27 | 728 | init = move (init); |
c38086bd | 729 | |
69821268 | 730 | if (DECL_NAME (field)) |
ebd21de4 | 731 | init = cp_build_modify_expr (comp, NOP_EXPR, init, |
732 | tf_warning_or_error); | |
69821268 | 733 | else |
7880033a | 734 | init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init); |
735 | finish_expr_stmt (init); | |
c38086bd | 736 | } |
737 | } | |
0a8302dc | 738 | finish_return_stmt (current_class_ref); |
68f8f8cc | 739 | finish_compound_stmt (compound_stmt); |
c38086bd | 740 | } |
741 | ||
b7102079 | 742 | /* Synthesize FNDECL, a non-static member function. */ |
743 | ||
c38086bd | 744 | void |
805e22b2 | 745 | synthesize_method (tree fndecl) |
c38086bd | 746 | { |
805e22b2 | 747 | bool nested = (current_function_decl != NULL_TREE); |
9ba4048d | 748 | tree context = decl_function_context (fndecl); |
805e22b2 | 749 | bool need_body = true; |
52616263 | 750 | tree stmt; |
8440403e | 751 | location_t save_input_location = input_location; |
b7102079 | 752 | int error_count = errorcount; |
d9d1b0a4 | 753 | int warning_count = warningcount + werrorcount; |
c25194fd | 754 | |
b7102079 | 755 | /* Reset the source location, we might have been previously |
756 | deferred, and thus have saved where we were first needed. */ | |
757 | DECL_SOURCE_LOCATION (fndecl) | |
758 | = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl))); | |
9031d10b | 759 | |
e55cba4c | 760 | /* If we've been asked to synthesize a clone, just synthesize the |
761 | cloned function instead. Doing so will automatically fill in the | |
762 | body for the clone. */ | |
763 | if (DECL_CLONED_FUNCTION_P (fndecl)) | |
b7102079 | 764 | fndecl = DECL_CLONED_FUNCTION (fndecl); |
e55cba4c | 765 | |
e8a37e53 | 766 | /* We may be in the middle of deferred access check. Disable |
767 | it now. */ | |
768 | push_deferring_access_checks (dk_no_deferred); | |
769 | ||
38281c46 | 770 | if (! context) |
771 | push_to_top_level (); | |
772 | else if (nested) | |
d2764e2d | 773 | push_function_context (); |
c25194fd | 774 | |
8440403e | 775 | input_location = DECL_SOURCE_LOCATION (fndecl); |
0a8302dc | 776 | |
3046c0a3 | 777 | start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED); |
52616263 | 778 | stmt = begin_function_body (); |
c25194fd | 779 | |
97cc4539 | 780 | if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR) |
0a8302dc | 781 | { |
ab8002de | 782 | do_build_copy_assign (fndecl); |
805e22b2 | 783 | need_body = false; |
0a8302dc | 784 | } |
7e3e1bb9 | 785 | else if (DECL_CONSTRUCTOR_P (fndecl)) |
c25194fd | 786 | { |
dcbeb3ef | 787 | tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl); |
c25194fd | 788 | if (arg_chain != void_list_node) |
789 | do_build_copy_constructor (fndecl); | |
e59b9381 | 790 | else |
7e3e1bb9 | 791 | finish_mem_initializers (NULL_TREE); |
0a8302dc | 792 | } |
2ee03578 | 793 | |
0a8302dc | 794 | /* If we haven't yet generated the body of the function, just |
795 | generate an empty compound statement. */ | |
796 | if (need_body) | |
797 | { | |
798 | tree compound_stmt; | |
2363ef00 | 799 | compound_stmt = begin_compound_stmt (BCS_FN_BODY); |
68f8f8cc | 800 | finish_compound_stmt (compound_stmt); |
c25194fd | 801 | } |
802 | ||
52616263 | 803 | finish_function_body (stmt); |
6cb758f0 | 804 | expand_or_defer_fn (finish_function (0)); |
bea7d742 | 805 | |
8440403e | 806 | input_location = save_input_location; |
807 | ||
38281c46 | 808 | if (! context) |
809 | pop_from_top_level (); | |
810 | else if (nested) | |
d2764e2d | 811 | pop_function_context (); |
e8a37e53 | 812 | |
813 | pop_deferring_access_checks (); | |
b7102079 | 814 | |
d9d1b0a4 | 815 | if (error_count != errorcount || warning_count != warningcount + werrorcount) |
5bcc316e | 816 | inform (input_location, "synthesized method %qD first required here ", |
817 | fndecl); | |
c38086bd | 818 | } |
cfb46e1f | 819 | |
2ee92e27 | 820 | /* Build a reference to type TYPE with cv-quals QUALS, which is an |
821 | rvalue if RVALUE is true. */ | |
d8ae7647 | 822 | |
823 | static tree | |
2ee92e27 | 824 | build_stub_type (tree type, int quals, bool rvalue) |
d8ae7647 | 825 | { |
2ee92e27 | 826 | tree argtype = cp_build_qualified_type (type, quals); |
827 | return cp_build_reference_type (argtype, rvalue); | |
828 | } | |
301679fe | 829 | |
2ee92e27 | 830 | /* Build a dummy glvalue from dereferencing a dummy reference of type |
831 | REFTYPE. */ | |
9031d10b | 832 | |
2ee92e27 | 833 | static tree |
834 | build_stub_object (tree reftype) | |
835 | { | |
f76a9aa8 | 836 | if (TREE_CODE (reftype) != REFERENCE_TYPE) |
837 | reftype = cp_build_reference_type (reftype, /*rval*/true); | |
ff4e692a | 838 | tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node); |
2ee92e27 | 839 | return convert_from_reference (stub); |
840 | } | |
9031d10b | 841 | |
2ee92e27 | 842 | /* Determine which function will be called when looking up NAME in TYPE, |
843 | called with a single ARGTYPE argument, or no argument if ARGTYPE is | |
844 | null. FLAGS and COMPLAIN are as for build_new_method_call. | |
9031d10b | 845 | |
2ee92e27 | 846 | Returns a FUNCTION_DECL if all is well. |
847 | Returns NULL_TREE if overload resolution failed. | |
848 | Returns error_mark_node if the chosen function cannot be called. */ | |
9031d10b | 849 | |
2ee92e27 | 850 | static tree |
851 | locate_fn_flags (tree type, tree name, tree argtype, int flags, | |
852 | tsubst_flags_t complain) | |
853 | { | |
854 | tree ob, fn, fns, binfo, rval; | |
f1f41a6c | 855 | vec<tree, va_gc> *args; |
2ee92e27 | 856 | |
857 | if (TYPE_P (type)) | |
858 | binfo = TYPE_BINFO (type); | |
859 | else | |
860 | { | |
861 | binfo = type; | |
862 | type = BINFO_TYPE (binfo); | |
863 | } | |
864 | ||
865 | ob = build_stub_object (cp_build_reference_type (type, false)); | |
866 | args = make_tree_vector (); | |
867 | if (argtype) | |
868 | { | |
fa6e8832 | 869 | if (TREE_CODE (argtype) == TREE_LIST) |
870 | { | |
871 | for (tree elt = argtype; elt != void_list_node; | |
872 | elt = TREE_CHAIN (elt)) | |
873 | { | |
874 | tree type = TREE_VALUE (elt); | |
fa6e8832 | 875 | tree arg = build_stub_object (type); |
f1f41a6c | 876 | vec_safe_push (args, arg); |
fa6e8832 | 877 | } |
878 | } | |
879 | else | |
880 | { | |
881 | tree arg = build_stub_object (argtype); | |
f1f41a6c | 882 | args->quick_push (arg); |
fa6e8832 | 883 | } |
d8ae7647 | 884 | } |
2ee92e27 | 885 | |
886 | fns = lookup_fnfields (binfo, name, 0); | |
887 | rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain); | |
888 | ||
889 | release_tree_vector (args); | |
890 | if (fn && rval == error_mark_node) | |
891 | return rval; | |
892 | else | |
893 | return fn; | |
d8ae7647 | 894 | } |
895 | ||
896 | /* Locate the dtor of TYPE. */ | |
897 | ||
481451eb | 898 | tree |
9b222de3 | 899 | get_dtor (tree type, tsubst_flags_t complain) |
d8ae7647 | 900 | { |
f66fb566 | 901 | tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE, |
9b222de3 | 902 | LOOKUP_NORMAL, complain); |
2ee92e27 | 903 | if (fn == error_mark_node) |
904 | return NULL_TREE; | |
905 | return fn; | |
d8ae7647 | 906 | } |
907 | ||
908 | /* Locate the default ctor of TYPE. */ | |
909 | ||
481451eb | 910 | tree |
2ee92e27 | 911 | locate_ctor (tree type) |
d8ae7647 | 912 | { |
8d96fd47 | 913 | tree fn; |
914 | ||
915 | push_deferring_access_checks (dk_no_check); | |
916 | fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, | |
917 | LOOKUP_SPECULATIVE, tf_none); | |
918 | pop_deferring_access_checks (); | |
2ee92e27 | 919 | if (fn == error_mark_node) |
920 | return NULL_TREE; | |
921 | return fn; | |
922 | } | |
923 | ||
924 | /* Likewise, but give any appropriate errors. */ | |
9031d10b | 925 | |
2ee92e27 | 926 | tree |
927 | get_default_ctor (tree type) | |
928 | { | |
929 | tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, | |
930 | LOOKUP_NORMAL, tf_warning_or_error); | |
931 | if (fn == error_mark_node) | |
932 | return NULL_TREE; | |
933 | return fn; | |
934 | } | |
935 | ||
936 | /* Locate the copy ctor of TYPE. */ | |
937 | ||
938 | tree | |
9b222de3 | 939 | get_copy_ctor (tree type, tsubst_flags_t complain) |
2ee92e27 | 940 | { |
941 | int quals = (TYPE_HAS_CONST_COPY_CTOR (type) | |
942 | ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); | |
943 | tree argtype = build_stub_type (type, quals, false); | |
944 | tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype, | |
9b222de3 | 945 | LOOKUP_NORMAL, complain); |
2ee92e27 | 946 | if (fn == error_mark_node) |
d8ae7647 | 947 | return NULL_TREE; |
2ee92e27 | 948 | return fn; |
949 | } | |
de5ab3f1 | 950 | |
2ee92e27 | 951 | /* Locate the copy assignment operator of TYPE. */ |
1827796b | 952 | |
2ee92e27 | 953 | tree |
954 | get_copy_assign (tree type) | |
955 | { | |
956 | int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type) | |
957 | ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); | |
958 | tree argtype = build_stub_type (type, quals, false); | |
959 | tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype, | |
960 | LOOKUP_NORMAL, tf_warning_or_error); | |
961 | if (fn == error_mark_node) | |
962 | return NULL_TREE; | |
963 | return fn; | |
964 | } | |
965 | ||
c9b99c30 | 966 | /* Locate the inherited constructor of constructor CTOR. */ |
967 | ||
968 | tree | |
969 | get_inherited_ctor (tree ctor) | |
970 | { | |
971 | gcc_assert (DECL_INHERITED_CTOR_BASE (ctor)); | |
972 | ||
973 | push_deferring_access_checks (dk_no_check); | |
974 | tree fn = locate_fn_flags (DECL_INHERITED_CTOR_BASE (ctor), | |
975 | complete_ctor_identifier, | |
976 | FUNCTION_FIRST_USER_PARMTYPE (ctor), | |
977 | LOOKUP_NORMAL|LOOKUP_SPECULATIVE, | |
978 | tf_none); | |
979 | pop_deferring_access_checks (); | |
980 | if (fn == error_mark_node) | |
981 | return NULL_TREE; | |
982 | return fn; | |
983 | } | |
984 | ||
f76a9aa8 | 985 | /* walk_tree helper function for is_trivially_xible. If *TP is a call, |
986 | return it if it calls something other than a trivial special member | |
987 | function. */ | |
988 | ||
989 | static tree | |
990 | check_nontriv (tree *tp, int *, void *) | |
991 | { | |
992 | tree fn; | |
993 | if (TREE_CODE (*tp) == CALL_EXPR) | |
994 | fn = CALL_EXPR_FN (*tp); | |
995 | else if (TREE_CODE (*tp) == AGGR_INIT_EXPR) | |
996 | fn = AGGR_INIT_EXPR_FN (*tp); | |
997 | else | |
998 | return NULL_TREE; | |
999 | ||
1000 | if (TREE_CODE (fn) == ADDR_EXPR) | |
1001 | fn = TREE_OPERAND (fn, 0); | |
1002 | ||
1003 | if (TREE_CODE (fn) != FUNCTION_DECL | |
1004 | || !trivial_fn_p (fn)) | |
1005 | return fn; | |
1006 | return NULL_TREE; | |
1007 | } | |
1008 | ||
1009 | /* Return declval<T>() = declval<U>() treated as an unevaluated operand. */ | |
1010 | ||
1011 | static tree | |
1012 | assignable_expr (tree to, tree from) | |
1013 | { | |
1014 | ++cp_unevaluated_operand; | |
1015 | to = build_stub_object (to); | |
1016 | from = build_stub_object (from); | |
1017 | tree r = cp_build_modify_expr (to, NOP_EXPR, from, tf_none); | |
1018 | --cp_unevaluated_operand; | |
1019 | return r; | |
1020 | } | |
1021 | ||
1022 | /* The predicate condition for a template specialization | |
1023 | is_constructible<T, Args...> shall be satisfied if and only if the | |
1024 | following variable definition would be well-formed for some invented | |
1025 | variable t: T t(create<Args>()...); | |
1026 | ||
1027 | Return something equivalent in well-formedness and triviality. */ | |
1028 | ||
1029 | static tree | |
1030 | constructible_expr (tree to, tree from) | |
1031 | { | |
1032 | tree expr; | |
1033 | if (CLASS_TYPE_P (to)) | |
1034 | { | |
1035 | tree ctype = to; | |
1036 | vec<tree, va_gc> *args = NULL; | |
1037 | if (TREE_CODE (to) != REFERENCE_TYPE) | |
1038 | to = cp_build_reference_type (to, /*rval*/false); | |
1039 | tree ob = build_stub_object (to); | |
1040 | for (; from; from = TREE_CHAIN (from)) | |
1041 | vec_safe_push (args, build_stub_object (TREE_VALUE (from))); | |
1042 | expr = build_special_member_call (ob, complete_ctor_identifier, &args, | |
1043 | ctype, LOOKUP_NORMAL, tf_none); | |
1044 | if (expr == error_mark_node) | |
1045 | return error_mark_node; | |
1046 | /* The current state of the standard vis-a-vis LWG 2116 is that | |
1047 | is_*constructible involves destruction as well. */ | |
1048 | if (type_build_dtor_call (ctype)) | |
1049 | { | |
1050 | tree dtor = build_special_member_call (ob, complete_dtor_identifier, | |
1051 | NULL, ctype, LOOKUP_NORMAL, | |
1052 | tf_none); | |
1053 | if (dtor == error_mark_node) | |
1054 | return error_mark_node; | |
1055 | if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (ctype)) | |
1056 | expr = build2 (COMPOUND_EXPR, void_type_node, expr, dtor); | |
1057 | } | |
1058 | } | |
1059 | else | |
1060 | { | |
1a80dd4a | 1061 | if (from == NULL_TREE) |
1062 | return build_value_init (to, tf_none); | |
1063 | else if (TREE_CHAIN (from)) | |
f76a9aa8 | 1064 | return error_mark_node; // too many initializers |
1065 | from = build_stub_object (TREE_VALUE (from)); | |
1066 | expr = perform_direct_initialization_if_possible (to, from, | |
1067 | /*cast*/false, | |
1068 | tf_none); | |
1069 | } | |
1070 | return expr; | |
1071 | } | |
1072 | ||
1073 | /* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or | |
1074 | constructible (otherwise) from FROM, which is a single type for | |
1075 | assignment or a list of types for construction. */ | |
1076 | ||
1077 | bool | |
1078 | is_trivially_xible (enum tree_code code, tree to, tree from) | |
1079 | { | |
1080 | tree expr; | |
1081 | if (code == MODIFY_EXPR) | |
1082 | expr = assignable_expr (to, from); | |
1083 | else if (from && TREE_CHAIN (from)) | |
1084 | return false; // only 0- and 1-argument ctors can be trivial | |
1085 | else | |
1086 | expr = constructible_expr (to, from); | |
1087 | ||
1088 | if (expr == error_mark_node) | |
1089 | return false; | |
1090 | tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL); | |
1091 | return !nt; | |
1092 | } | |
1093 | ||
2ee92e27 | 1094 | /* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and |
1095 | DELETED_P or give an error message MSG with argument ARG. */ | |
1096 | ||
1097 | static void | |
ecb10e6a | 1098 | process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, |
1099 | bool *deleted_p, bool *constexpr_p, | |
f018a23c | 1100 | bool diag, tree arg) |
2ee92e27 | 1101 | { |
1102 | if (!fn || fn == error_mark_node) | |
1103 | goto bad; | |
1104 | ||
1105 | if (spec_p) | |
d8ae7647 | 1106 | { |
f2c1aabc | 1107 | maybe_instantiate_noexcept (fn); |
3239620b | 1108 | tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); |
f2c1aabc | 1109 | *spec_p = merge_exception_specifiers (*spec_p, raises); |
2ee92e27 | 1110 | } |
9031d10b | 1111 | |
80e54732 | 1112 | if (!trivial_fn_p (fn)) |
1113 | { | |
1114 | if (trivial_p) | |
1115 | *trivial_p = false; | |
1116 | if (TREE_CODE (arg) == FIELD_DECL | |
1117 | && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE) | |
1118 | { | |
1119 | if (deleted_p) | |
1120 | *deleted_p = true; | |
f018a23c | 1121 | if (diag) |
80e54732 | 1122 | error ("union member %q+D with non-trivial %qD", arg, fn); |
1123 | } | |
1124 | } | |
2671dfdf | 1125 | |
bbab4abf | 1126 | if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn)) |
611b6173 | 1127 | { |
bbab4abf | 1128 | *constexpr_p = false; |
f018a23c | 1129 | if (diag) |
262c8920 | 1130 | { |
66ed189d | 1131 | inform (DECL_SOURCE_LOCATION (fn), |
1132 | "defaulted constructor calls non-constexpr %qD", fn); | |
bbab4abf | 1133 | explain_invalid_constexpr_fn (fn); |
262c8920 | 1134 | } |
611b6173 | 1135 | } |
e8fa380d | 1136 | |
2ee92e27 | 1137 | return; |
1138 | ||
1139 | bad: | |
1140 | if (deleted_p) | |
1141 | *deleted_p = true; | |
d8ae7647 | 1142 | } |
1143 | ||
80e54732 | 1144 | /* Subroutine of synthesized_method_walk to allow recursion into anonymous |
1145 | aggregates. */ | |
1146 | ||
1147 | static void | |
1148 | walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, | |
1149 | int quals, bool copy_arg_p, bool move_p, | |
1150 | bool assign_p, tree *spec_p, bool *trivial_p, | |
ecb10e6a | 1151 | bool *deleted_p, bool *constexpr_p, |
f018a23c | 1152 | bool diag, int flags, tsubst_flags_t complain) |
80e54732 | 1153 | { |
1154 | tree field; | |
1767a056 | 1155 | for (field = fields; field; field = DECL_CHAIN (field)) |
80e54732 | 1156 | { |
1157 | tree mem_type, argtype, rval; | |
1158 | ||
1159 | if (TREE_CODE (field) != FIELD_DECL | |
1160 | || DECL_ARTIFICIAL (field)) | |
1161 | continue; | |
1162 | ||
1163 | mem_type = strip_array_types (TREE_TYPE (field)); | |
1164 | if (assign_p) | |
1165 | { | |
1166 | bool bad = true; | |
1167 | if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type)) | |
1168 | { | |
f018a23c | 1169 | if (diag) |
bf776685 | 1170 | error ("non-static const member %q#D, can%'t use default " |
80e54732 | 1171 | "assignment operator", field); |
1172 | } | |
1173 | else if (TREE_CODE (mem_type) == REFERENCE_TYPE) | |
1174 | { | |
f018a23c | 1175 | if (diag) |
bf776685 | 1176 | error ("non-static reference member %q#D, can%'t use " |
80e54732 | 1177 | "default assignment operator", field); |
1178 | } | |
1179 | else | |
1180 | bad = false; | |
1181 | ||
1182 | if (bad && deleted_p) | |
1183 | *deleted_p = true; | |
1184 | } | |
1185 | else if (sfk == sfk_constructor) | |
1186 | { | |
f0ccda52 | 1187 | bool bad; |
e8fa380d | 1188 | |
d9c249a4 | 1189 | if (DECL_INITIAL (field)) |
1190 | { | |
f018a23c | 1191 | if (diag && DECL_INITIAL (field) == error_mark_node) |
66ed189d | 1192 | inform (DECL_SOURCE_LOCATION (field), |
1193 | "initializer for %q#D is invalid", field); | |
d9c249a4 | 1194 | if (trivial_p) |
1195 | *trivial_p = false; | |
12391171 | 1196 | /* Core 1351: If the field has an NSDMI that could throw, the |
f2c1aabc | 1197 | default constructor is noexcept(false). */ |
1198 | if (spec_p) | |
1199 | { | |
1200 | tree nsdmi = get_nsdmi (field, /*ctor*/false); | |
1201 | if (!expr_noexcept_p (nsdmi, complain)) | |
1202 | *spec_p = noexcept_false_spec; | |
1203 | } | |
d9c249a4 | 1204 | /* Don't do the normal processing. */ |
1205 | continue; | |
1206 | } | |
1207 | ||
f0ccda52 | 1208 | bad = false; |
1209 | if (CP_TYPE_CONST_P (mem_type) | |
1210 | && default_init_uninitialized_part (mem_type)) | |
1211 | { | |
f018a23c | 1212 | if (diag) |
bebb2c46 | 1213 | { |
1214 | error ("uninitialized const member in %q#T", | |
1215 | current_class_type); | |
1216 | inform (DECL_SOURCE_LOCATION (field), | |
1217 | "%q#D should be initialized", field); | |
1218 | } | |
f0ccda52 | 1219 | bad = true; |
1220 | } | |
1221 | else if (TREE_CODE (mem_type) == REFERENCE_TYPE) | |
1222 | { | |
f018a23c | 1223 | if (diag) |
bebb2c46 | 1224 | { |
1225 | error ("uninitialized reference member in %q#T", | |
1226 | current_class_type); | |
1227 | inform (DECL_SOURCE_LOCATION (field), | |
1228 | "%q#D should be initialized", field); | |
1229 | } | |
f0ccda52 | 1230 | bad = true; |
1231 | } | |
1232 | ||
1233 | if (bad && deleted_p) | |
1234 | *deleted_p = true; | |
1235 | ||
e8fa380d | 1236 | /* For an implicitly-defined default constructor to be constexpr, |
d9c249a4 | 1237 | every member must have a user-provided default constructor or |
1238 | an explicit initializer. */ | |
2425eec7 | 1239 | if (constexpr_p && !CLASS_TYPE_P (mem_type) |
1240 | && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE) | |
262c8920 | 1241 | { |
1242 | *constexpr_p = false; | |
f018a23c | 1243 | if (diag) |
66ed189d | 1244 | inform (DECL_SOURCE_LOCATION (field), |
1245 | "defaulted default constructor does not " | |
1246 | "initialize %q#D", field); | |
262c8920 | 1247 | } |
80e54732 | 1248 | } |
23d471c1 | 1249 | else if (sfk == sfk_copy_constructor) |
1250 | { | |
1251 | /* 12.8p11b5 */ | |
1252 | if (TREE_CODE (mem_type) == REFERENCE_TYPE | |
1253 | && TYPE_REF_IS_RVALUE (mem_type)) | |
1254 | { | |
1255 | if (diag) | |
1256 | error ("copying non-static data member %q#D of rvalue " | |
1257 | "reference type", field); | |
1258 | if (deleted_p) | |
1259 | *deleted_p = true; | |
1260 | } | |
1261 | } | |
80e54732 | 1262 | |
1263 | if (!CLASS_TYPE_P (mem_type)) | |
1264 | continue; | |
1265 | ||
1266 | if (ANON_AGGR_TYPE_P (mem_type)) | |
1267 | { | |
1268 | walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals, | |
1269 | copy_arg_p, move_p, assign_p, spec_p, trivial_p, | |
ecb10e6a | 1270 | deleted_p, constexpr_p, |
f018a23c | 1271 | diag, flags, complain); |
80e54732 | 1272 | continue; |
1273 | } | |
1274 | ||
1275 | if (copy_arg_p) | |
1276 | { | |
1277 | int mem_quals = cp_type_quals (mem_type) | quals; | |
1278 | if (DECL_MUTABLE_P (field)) | |
1279 | mem_quals &= ~TYPE_QUAL_CONST; | |
1280 | argtype = build_stub_type (mem_type, mem_quals, move_p); | |
1281 | } | |
1282 | else | |
1283 | argtype = NULL_TREE; | |
1284 | ||
1285 | rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); | |
1286 | ||
ecb10e6a | 1287 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1288 | constexpr_p, diag, field); | |
80e54732 | 1289 | } |
1290 | } | |
1291 | ||
2ee92e27 | 1292 | /* The caller wants to generate an implicit declaration of SFK for CTYPE |
1293 | which is const if relevant and CONST_P is set. If spec_p, trivial_p and | |
1294 | deleted_p are non-null, set their referent appropriately. If diag is | |
262c8920 | 1295 | true, we're either being called from maybe_explain_implicit_delete to |
1296 | give errors, or if constexpr_p is non-null, from | |
1297 | explain_invalid_constexpr_fn. */ | |
2ee92e27 | 1298 | |
1299 | static void | |
1300 | synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, | |
1301 | tree *spec_p, bool *trivial_p, bool *deleted_p, | |
ecb10e6a | 1302 | bool *constexpr_p, bool diag, |
fa6e8832 | 1303 | tree inherited_base, tree inherited_parms) |
d8ae7647 | 1304 | { |
80e54732 | 1305 | tree binfo, base_binfo, scope, fnname, rval, argtype; |
2ee92e27 | 1306 | bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor; |
f1f41a6c | 1307 | vec<tree, va_gc> *vbases; |
2ee92e27 | 1308 | int i, quals, flags; |
1309 | tsubst_flags_t complain; | |
85acc8c4 | 1310 | bool ctor_p; |
2ee92e27 | 1311 | |
1312 | if (spec_p) | |
60777f69 | 1313 | *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec); |
2ee92e27 | 1314 | |
1315 | if (deleted_p) | |
1316 | { | |
1317 | /* "The closure type associated with a lambda-expression has a deleted | |
1318 | default constructor and a deleted copy assignment operator." | |
1319 | This is diagnosed in maybe_explain_implicit_delete. */ | |
1320 | if (LAMBDA_TYPE_P (ctype) | |
1321 | && (sfk == sfk_constructor | |
1322 | || sfk == sfk_copy_assignment)) | |
1323 | { | |
1324 | *deleted_p = true; | |
1325 | return; | |
1326 | } | |
d8ae7647 | 1327 | |
2ee92e27 | 1328 | *deleted_p = false; |
1329 | } | |
d8ae7647 | 1330 | |
e8fa380d | 1331 | ctor_p = false; |
1332 | assign_p = false; | |
1333 | check_vdtor = false; | |
1334 | switch (sfk) | |
1335 | { | |
1336 | case sfk_move_assignment: | |
1337 | case sfk_copy_assignment: | |
1338 | assign_p = true; | |
1339 | fnname = ansi_assopname (NOP_EXPR); | |
1340 | break; | |
1341 | ||
1342 | case sfk_destructor: | |
1343 | check_vdtor = true; | |
1344 | /* The synthesized method will call base dtors, but check complete | |
1345 | here to avoid having to deal with VTT. */ | |
1346 | fnname = complete_dtor_identifier; | |
1347 | break; | |
1348 | ||
1349 | case sfk_constructor: | |
1350 | case sfk_move_constructor: | |
1351 | case sfk_copy_constructor: | |
fa6e8832 | 1352 | case sfk_inheriting_constructor: |
e8fa380d | 1353 | ctor_p = true; |
1354 | fnname = complete_ctor_identifier; | |
1355 | break; | |
1356 | ||
1357 | default: | |
1358 | gcc_unreachable (); | |
1359 | } | |
1360 | ||
fa6e8832 | 1361 | gcc_assert ((sfk == sfk_inheriting_constructor) |
1362 | == (inherited_base != NULL_TREE)); | |
1363 | ||
e8fa380d | 1364 | /* If that user-written default constructor would satisfy the |
1365 | requirements of a constexpr constructor (7.1.5), the | |
1366 | implicitly-defined default constructor is constexpr. */ | |
1367 | if (constexpr_p) | |
1368 | *constexpr_p = ctor_p; | |
1369 | ||
2ee92e27 | 1370 | move_p = false; |
1371 | switch (sfk) | |
1372 | { | |
1373 | case sfk_constructor: | |
1374 | case sfk_destructor: | |
fa6e8832 | 1375 | case sfk_inheriting_constructor: |
2ee92e27 | 1376 | copy_arg_p = false; |
1377 | break; | |
1378 | ||
1379 | case sfk_move_constructor: | |
1380 | case sfk_move_assignment: | |
1381 | move_p = true; | |
1382 | case sfk_copy_constructor: | |
1383 | case sfk_copy_assignment: | |
1384 | copy_arg_p = true; | |
1385 | break; | |
1386 | ||
1387 | default: | |
1388 | gcc_unreachable (); | |
1389 | } | |
1390 | ||
1391 | expected_trivial = type_has_trivial_fn (ctype, sfk); | |
1392 | if (trivial_p) | |
1393 | *trivial_p = expected_trivial; | |
1394 | ||
2ee92e27 | 1395 | /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base |
1396 | class versions and other properties of the type. But a subobject | |
1397 | class can be trivially copyable and yet have overload resolution | |
1398 | choose a template constructor for initialization, depending on | |
575852de | 1399 | rvalueness and cv-quals. And furthermore, a member in a base might |
1400 | be trivial but deleted or otherwise not callable. So we can't exit | |
1401 | early in C++0x. The same considerations apply in C++98/03, but | |
92b327d3 | 1402 | there the definition of triviality does not consider overload |
1403 | resolution, so a constructor can be trivial even if it would otherwise | |
1404 | call a non-trivial constructor. */ | |
2ee92e27 | 1405 | if (expected_trivial |
60777f69 | 1406 | && (!copy_arg_p || cxx_dialect < cxx11)) |
c3170ce3 | 1407 | { |
1408 | if (constexpr_p && sfk == sfk_constructor) | |
2425eec7 | 1409 | { |
1410 | bool cx = trivial_default_constructor_is_constexpr (ctype); | |
1411 | *constexpr_p = cx; | |
1412 | if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE) | |
1413 | /* A trivial constructor doesn't have any NSDMI. */ | |
1414 | inform (input_location, "defaulted default constructor does " | |
1415 | "not initialize any non-static data member"); | |
1416 | } | |
575852de | 1417 | if (!diag && cxx_dialect < cxx11) |
2425eec7 | 1418 | return; |
c3170ce3 | 1419 | } |
9031d10b | 1420 | |
2ee92e27 | 1421 | ++cp_unevaluated_operand; |
1422 | ++c_inhibit_evaluation_warnings; | |
eb833cbe | 1423 | push_deferring_access_checks (dk_no_deferred); |
2ee92e27 | 1424 | |
1425 | scope = push_scope (ctype); | |
1426 | ||
fa6e8832 | 1427 | flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE; |
1428 | if (!inherited_base) | |
1429 | flags |= LOOKUP_DEFAULTED; | |
c4698a21 | 1430 | |
1431 | complain = diag ? tf_warning_or_error : tf_none; | |
52341212 | 1432 | |
2ee92e27 | 1433 | if (const_p) |
1434 | quals = TYPE_QUAL_CONST; | |
1435 | else | |
1436 | quals = TYPE_UNQUALIFIED; | |
1437 | argtype = NULL_TREE; | |
52341212 | 1438 | |
2ee92e27 | 1439 | for (binfo = TYPE_BINFO (ctype), i = 0; |
1440 | BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) | |
1441 | { | |
1442 | tree basetype = BINFO_TYPE (base_binfo); | |
f018a23c | 1443 | |
1444 | if (!assign_p && BINFO_VIRTUAL_P (base_binfo)) | |
1445 | /* We'll handle virtual bases below. */ | |
1446 | continue; | |
1447 | ||
2ee92e27 | 1448 | if (copy_arg_p) |
1449 | argtype = build_stub_type (basetype, quals, move_p); | |
fa6e8832 | 1450 | else if (basetype == inherited_base) |
1451 | argtype = inherited_parms; | |
2ee92e27 | 1452 | rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); |
fa6e8832 | 1453 | if (inherited_base) |
1454 | argtype = NULL_TREE; | |
2ee92e27 | 1455 | |
ecb10e6a | 1456 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1457 | constexpr_p, diag, basetype); | |
575852de | 1458 | if (ctor_p) |
85acc8c4 | 1459 | { |
1460 | /* In a constructor we also need to check the subobject | |
1461 | destructors for cleanup of partially constructed objects. */ | |
1462 | rval = locate_fn_flags (base_binfo, complete_dtor_identifier, | |
1463 | NULL_TREE, flags, complain); | |
aafa0794 | 1464 | /* Note that we don't pass down trivial_p; the subobject |
8919e4f8 | 1465 | destructors don't affect triviality of the constructor. Nor |
1466 | do they affect constexpr-ness (a constant expression doesn't | |
1467 | throw) or exception-specification (a throw from one of the | |
1468 | dtors would be a double-fault). */ | |
ecb10e6a | 1469 | process_subob_fn (rval, NULL, NULL, |
1470 | deleted_p, NULL, false, | |
e8fa380d | 1471 | basetype); |
85acc8c4 | 1472 | } |
2ee92e27 | 1473 | |
1474 | if (check_vdtor && type_has_virtual_destructor (basetype)) | |
1475 | { | |
1476 | rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR), | |
1477 | ptr_type_node, flags, complain); | |
1478 | /* Unlike for base ctor/op=/dtor, for operator delete it's fine | |
1479 | to have a null rval (no class-specific op delete). */ | |
1480 | if (rval && rval == error_mark_node && deleted_p) | |
1481 | *deleted_p = true; | |
85acc8c4 | 1482 | check_vdtor = false; |
2ee92e27 | 1483 | } |
ecb10e6a | 1484 | |
1485 | if (diag && assign_p && move_p | |
1486 | && BINFO_VIRTUAL_P (base_binfo) | |
1487 | && rval && TREE_CODE (rval) == FUNCTION_DECL | |
ac417619 | 1488 | && move_fn_p (rval) && !trivial_fn_p (rval) |
1489 | && vbase_has_user_provided_move_assign (basetype)) | |
ecb10e6a | 1490 | warning (OPT_Wvirtual_move_assign, |
1491 | "defaulted move assignment for %qT calls a non-trivial " | |
1492 | "move assignment operator for virtual base %qT", | |
1493 | ctype, basetype); | |
2ee92e27 | 1494 | } |
1495 | ||
1496 | vbases = CLASSTYPE_VBASECLASSES (ctype); | |
d86e71c1 | 1497 | if (vec_safe_is_empty (vbases)) |
f018a23c | 1498 | /* No virtual bases to worry about. */; |
2ee92e27 | 1499 | else if (!assign_p) |
2ee92e27 | 1500 | { |
f018a23c | 1501 | if (constexpr_p) |
e8fa380d | 1502 | *constexpr_p = false; |
f1f41a6c | 1503 | FOR_EACH_VEC_ELT (*vbases, i, base_binfo) |
2ee92e27 | 1504 | { |
85acc8c4 | 1505 | tree basetype = BINFO_TYPE (base_binfo); |
80e54732 | 1506 | if (copy_arg_p) |
85acc8c4 | 1507 | argtype = build_stub_type (basetype, quals, move_p); |
80e54732 | 1508 | rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); |
2ee92e27 | 1509 | |
ecb10e6a | 1510 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1511 | constexpr_p, diag, basetype); | |
85acc8c4 | 1512 | if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype)) |
1513 | { | |
1514 | rval = locate_fn_flags (base_binfo, complete_dtor_identifier, | |
1515 | NULL_TREE, flags, complain); | |
ecb10e6a | 1516 | process_subob_fn (rval, NULL, NULL, |
1517 | deleted_p, NULL, false, | |
e8fa380d | 1518 | basetype); |
85acc8c4 | 1519 | } |
2ee92e27 | 1520 | } |
d8ae7647 | 1521 | } |
f018a23c | 1522 | |
1523 | /* Now handle the non-static data members. */ | |
80e54732 | 1524 | walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals, |
1525 | copy_arg_p, move_p, assign_p, spec_p, trivial_p, | |
ecb10e6a | 1526 | deleted_p, constexpr_p, |
f018a23c | 1527 | diag, flags, complain); |
85acc8c4 | 1528 | if (ctor_p) |
1529 | walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier, | |
1530 | sfk_destructor, TYPE_UNQUALIFIED, false, | |
118da0ff | 1531 | false, false, NULL, NULL, |
aafa0794 | 1532 | deleted_p, NULL, |
ecb10e6a | 1533 | false, flags, complain); |
2ee92e27 | 1534 | |
1535 | pop_scope (scope); | |
1536 | ||
eb833cbe | 1537 | pop_deferring_access_checks (); |
2ee92e27 | 1538 | --cp_unevaluated_operand; |
1539 | --c_inhibit_evaluation_warnings; | |
2ee92e27 | 1540 | } |
1541 | ||
f2c1aabc | 1542 | /* DECL is a defaulted function whose exception specification is now |
1543 | needed. Return what it should be. */ | |
1544 | ||
1545 | tree | |
1546 | get_defaulted_eh_spec (tree decl) | |
1547 | { | |
1548 | if (DECL_CLONED_FUNCTION_P (decl)) | |
1549 | decl = DECL_CLONED_FUNCTION (decl); | |
1550 | special_function_kind sfk = special_function_p (decl); | |
1551 | tree ctype = DECL_CONTEXT (decl); | |
1552 | tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl); | |
1553 | tree parm_type = TREE_VALUE (parms); | |
1554 | bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); | |
1555 | tree spec = empty_except_spec; | |
1556 | synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL, | |
1557 | NULL, false, DECL_INHERITED_CTOR_BASE (decl), | |
1558 | parms); | |
1559 | return spec; | |
1560 | } | |
1561 | ||
2ee92e27 | 1562 | /* DECL is a deleted function. If it's implicitly deleted, explain why and |
1563 | return true; else return false. */ | |
1564 | ||
1565 | bool | |
1566 | maybe_explain_implicit_delete (tree decl) | |
1567 | { | |
1568 | /* If decl is a clone, get the primary variant. */ | |
1569 | decl = DECL_ORIGIN (decl); | |
1570 | gcc_assert (DECL_DELETED_FN (decl)); | |
21f80a31 | 1571 | if (DECL_DEFAULTED_FN (decl)) |
2ee92e27 | 1572 | { |
1573 | /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */ | |
431205b7 | 1574 | static hash_set<tree> *explained; |
2ee92e27 | 1575 | |
1576 | special_function_kind sfk; | |
1577 | location_t loc; | |
1578 | bool informed; | |
1579 | tree ctype; | |
1580 | ||
68224783 | 1581 | if (!explained) |
431205b7 | 1582 | explained = new hash_set<tree>; |
1583 | if (explained->add (decl)) | |
2ee92e27 | 1584 | return true; |
2ee92e27 | 1585 | |
1586 | sfk = special_function_p (decl); | |
1587 | ctype = DECL_CONTEXT (decl); | |
1588 | loc = input_location; | |
1589 | input_location = DECL_SOURCE_LOCATION (decl); | |
1590 | ||
1591 | informed = false; | |
1592 | if (LAMBDA_TYPE_P (ctype)) | |
1593 | { | |
1594 | informed = true; | |
1595 | if (sfk == sfk_constructor) | |
b68e6235 | 1596 | inform (DECL_SOURCE_LOCATION (decl), |
1597 | "a lambda closure type has a deleted default constructor"); | |
2ee92e27 | 1598 | else if (sfk == sfk_copy_assignment) |
b68e6235 | 1599 | inform (DECL_SOURCE_LOCATION (decl), |
1600 | "a lambda closure type has a deleted copy assignment operator"); | |
2ee92e27 | 1601 | else |
1602 | informed = false; | |
1603 | } | |
b68e6235 | 1604 | else if (DECL_ARTIFICIAL (decl) |
1605 | && (sfk == sfk_copy_assignment | |
1606 | || sfk == sfk_copy_constructor) | |
1607 | && (type_has_user_declared_move_constructor (ctype) | |
1608 | || type_has_user_declared_move_assign (ctype))) | |
1609 | { | |
66ed189d | 1610 | inform (DECL_SOURCE_LOCATION (decl), |
1611 | "%q#D is implicitly declared as deleted because %qT " | |
1612 | "declares a move constructor or move assignment operator", | |
1613 | decl, ctype); | |
b68e6235 | 1614 | informed = true; |
1615 | } | |
2ee92e27 | 1616 | if (!informed) |
1617 | { | |
fa6e8832 | 1618 | tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl); |
1619 | tree parm_type = TREE_VALUE (parms); | |
2ee92e27 | 1620 | bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); |
92a94bec | 1621 | tree raises = NULL_TREE; |
1622 | bool deleted_p = false; | |
2ee92e27 | 1623 | tree scope = push_scope (ctype); |
92a94bec | 1624 | |
2ee92e27 | 1625 | synthesized_method_walk (ctype, sfk, const_p, |
92a94bec | 1626 | &raises, NULL, &deleted_p, NULL, false, |
fa6e8832 | 1627 | DECL_INHERITED_CTOR_BASE (decl), parms); |
92a94bec | 1628 | if (deleted_p) |
1629 | { | |
66ed189d | 1630 | inform (DECL_SOURCE_LOCATION (decl), |
1631 | "%q#D is implicitly deleted because the default " | |
92a94bec | 1632 | "definition would be ill-formed:", decl); |
1633 | synthesized_method_walk (ctype, sfk, const_p, | |
1634 | NULL, NULL, NULL, NULL, true, | |
1635 | DECL_INHERITED_CTOR_BASE (decl), parms); | |
1636 | } | |
1637 | else if (!comp_except_specs | |
1638 | (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)), | |
1639 | raises, ce_normal)) | |
1640 | inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly " | |
1641 | "deleted because its exception-specification does not " | |
1642 | "match the implicit exception-specification %qX", | |
1643 | decl, raises); | |
5e8689fb | 1644 | else if (flag_checking) |
92a94bec | 1645 | gcc_unreachable (); |
92a94bec | 1646 | |
1647 | pop_scope (scope); | |
2ee92e27 | 1648 | } |
1649 | ||
1650 | input_location = loc; | |
1651 | return true; | |
1652 | } | |
1653 | return false; | |
d8ae7647 | 1654 | } |
1655 | ||
262c8920 | 1656 | /* DECL is a defaulted function which was declared constexpr. Explain why |
1657 | it can't be constexpr. */ | |
1658 | ||
1659 | void | |
1660 | explain_implicit_non_constexpr (tree decl) | |
1661 | { | |
1662 | tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); | |
1663 | bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); | |
1664 | bool dummy; | |
1665 | synthesized_method_walk (DECL_CLASS_CONTEXT (decl), | |
1666 | special_function_p (decl), const_p, | |
ecb10e6a | 1667 | NULL, NULL, NULL, &dummy, true, |
9d3f4725 | 1668 | DECL_INHERITED_CTOR_BASE (decl), |
1669 | FUNCTION_FIRST_USER_PARMTYPE (decl)); | |
fa6e8832 | 1670 | } |
1671 | ||
1672 | /* DECL is an instantiation of an inheriting constructor template. Deduce | |
1673 | the correct exception-specification and deletedness for this particular | |
1674 | specialization. */ | |
1675 | ||
1676 | void | |
1677 | deduce_inheriting_ctor (tree decl) | |
1678 | { | |
1679 | gcc_assert (DECL_INHERITED_CTOR_BASE (decl)); | |
1680 | tree spec; | |
ecb10e6a | 1681 | bool trivial, constexpr_, deleted; |
fa6e8832 | 1682 | synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor, |
1683 | false, &spec, &trivial, &deleted, &constexpr_, | |
ecb10e6a | 1684 | /*diag*/false, |
fa6e8832 | 1685 | DECL_INHERITED_CTOR_BASE (decl), |
1686 | FUNCTION_FIRST_USER_PARMTYPE (decl)); | |
1687 | DECL_DELETED_FN (decl) = deleted; | |
1688 | TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec); | |
262c8920 | 1689 | } |
1690 | ||
cfb46e1f | 1691 | /* Implicitly declare the special function indicated by KIND, as a |
1692 | member of TYPE. For copy constructors and assignment operators, | |
1693 | CONST_P indicates whether these functions should take a const | |
6ecedd95 | 1694 | reference argument or a non-const reference. Returns the |
1695 | FUNCTION_DECL for the implicitly declared function. */ | |
cfb46e1f | 1696 | |
0568e5f9 | 1697 | tree |
fa6e8832 | 1698 | implicitly_declare_fn (special_function_kind kind, tree type, |
1699 | bool const_p, tree inherited_ctor, | |
1700 | tree inherited_parms) | |
cfb46e1f | 1701 | { |
3046c0a3 | 1702 | tree fn; |
1703 | tree parameter_types = void_list_node; | |
853b7640 | 1704 | tree return_type; |
3046c0a3 | 1705 | tree fn_type; |
d8ae7647 | 1706 | tree raises = empty_except_spec; |
3046c0a3 | 1707 | tree rhs_parm_type = NULL_TREE; |
7873fcd6 | 1708 | tree this_parm; |
3046c0a3 | 1709 | tree name; |
8223a66b | 1710 | HOST_WIDE_INT saved_processing_template_decl; |
2ee92e27 | 1711 | bool deleted_p; |
e8fa380d | 1712 | bool constexpr_p; |
8223a66b | 1713 | |
de16fecd | 1714 | /* Because we create declarations for implicitly declared functions |
8223a66b | 1715 | lazily, we may be creating the declaration for a member of TYPE |
1716 | while in some completely different context. However, TYPE will | |
1717 | never be a dependent class (because we never want to do lookups | |
1718 | for implicitly defined functions in a dependent class). | |
1719 | Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here | |
1720 | because we only create clones for constructors and destructors | |
1721 | when not in a template. */ | |
1722 | gcc_assert (!dependent_type_p (type)); | |
1723 | saved_processing_template_decl = processing_template_decl; | |
1724 | processing_template_decl = 0; | |
cfb46e1f | 1725 | |
1827796b | 1726 | type = TYPE_MAIN_VARIANT (type); |
1727 | ||
853b7640 | 1728 | if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type)) |
1729 | { | |
1730 | if (kind == sfk_destructor) | |
1731 | /* See comment in check_special_function_return_type. */ | |
1732 | return_type = build_pointer_type (void_type_node); | |
1733 | else | |
1734 | return_type = build_pointer_type (type); | |
1735 | } | |
1736 | else | |
1737 | return_type = void_type_node; | |
1738 | ||
cfb46e1f | 1739 | switch (kind) |
1740 | { | |
cfb46e1f | 1741 | case sfk_destructor: |
d8ae7647 | 1742 | /* Destructor. */ |
3046c0a3 | 1743 | name = constructor_name (type); |
cfb46e1f | 1744 | break; |
1745 | ||
1746 | case sfk_constructor: | |
1747 | /* Default constructor. */ | |
3046c0a3 | 1748 | name = constructor_name (type); |
cfb46e1f | 1749 | break; |
1750 | ||
1751 | case sfk_copy_constructor: | |
ab8002de | 1752 | case sfk_copy_assignment: |
a8b75081 | 1753 | case sfk_move_constructor: |
2ee92e27 | 1754 | case sfk_move_assignment: |
fa6e8832 | 1755 | case sfk_inheriting_constructor: |
d8ae7647 | 1756 | { |
2ee92e27 | 1757 | bool move_p; |
1758 | if (kind == sfk_copy_assignment | |
1759 | || kind == sfk_move_assignment) | |
653e5405 | 1760 | { |
3046c0a3 | 1761 | return_type = build_reference_type (type); |
653e5405 | 1762 | name = ansi_assopname (NOP_EXPR); |
653e5405 | 1763 | } |
3046c0a3 | 1764 | else |
1765 | name = constructor_name (type); | |
1766 | ||
fa6e8832 | 1767 | if (kind == sfk_inheriting_constructor) |
1768 | parameter_types = inherited_parms; | |
3046c0a3 | 1769 | else |
fa6e8832 | 1770 | { |
1771 | if (const_p) | |
1772 | rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST); | |
1773 | else | |
1774 | rhs_parm_type = type; | |
1775 | move_p = (kind == sfk_move_assignment | |
1776 | || kind == sfk_move_constructor); | |
1777 | rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p); | |
2ee92e27 | 1778 | |
fa6e8832 | 1779 | parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types); |
1780 | } | |
cfb46e1f | 1781 | break; |
d8ae7647 | 1782 | } |
cfb46e1f | 1783 | default: |
092b1d6f | 1784 | gcc_unreachable (); |
cfb46e1f | 1785 | } |
1786 | ||
fa6e8832 | 1787 | tree inherited_base = (inherited_ctor |
1788 | ? DECL_CONTEXT (inherited_ctor) | |
1789 | : NULL_TREE); | |
7b3e2ca8 | 1790 | bool trivial_p = false; |
1791 | ||
fa6e8832 | 1792 | if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL) |
1793 | { | |
1794 | /* For an inheriting constructor template, just copy these flags from | |
1795 | the inherited constructor template for now. */ | |
1796 | raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor)); | |
2d791ea6 | 1797 | deleted_p = DECL_DELETED_FN (inherited_ctor); |
1798 | constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor); | |
fa6e8832 | 1799 | } |
f2c1aabc | 1800 | else if (cxx_dialect >= cxx11) |
1801 | { | |
1802 | raises = unevaluated_noexcept_spec (); | |
1803 | synthesized_method_walk (type, kind, const_p, NULL, &trivial_p, | |
1804 | &deleted_p, &constexpr_p, false, | |
1805 | inherited_base, inherited_parms); | |
1806 | } | |
fa6e8832 | 1807 | else |
1808 | synthesized_method_walk (type, kind, const_p, &raises, &trivial_p, | |
ecb10e6a | 1809 | &deleted_p, &constexpr_p, false, |
fa6e8832 | 1810 | inherited_base, inherited_parms); |
e8fa380d | 1811 | /* Don't bother marking a deleted constructor as constexpr. */ |
1812 | if (deleted_p) | |
1813 | constexpr_p = false; | |
de782278 | 1814 | /* A trivial copy/move constructor is also a constexpr constructor, |
1815 | unless the class has virtual bases (7.1.5p4). */ | |
60777f69 | 1816 | else if (trivial_p && cxx_dialect >= cxx11 |
e8fa380d | 1817 | && (kind == sfk_copy_constructor |
de782278 | 1818 | || kind == sfk_move_constructor) |
1819 | && !CLASSTYPE_VBASECLASSES (type)) | |
e8fa380d | 1820 | gcc_assert (constexpr_p); |
2ee92e27 | 1821 | |
1822 | if (!trivial_p && type_has_trivial_fn (type, kind)) | |
1823 | type_set_nontrivial_flag (type, kind); | |
1824 | ||
3046c0a3 | 1825 | /* Create the function. */ |
1826 | fn_type = build_method_type_directly (type, return_type, parameter_types); | |
1827 | if (raises) | |
1828 | fn_type = build_exception_variant (fn_type, raises); | |
1829 | fn = build_lang_decl (FUNCTION_DECL, name, fn_type); | |
fa6e8832 | 1830 | if (kind != sfk_inheriting_constructor) |
1831 | DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type)); | |
a8b75081 | 1832 | if (kind == sfk_constructor || kind == sfk_copy_constructor |
fa6e8832 | 1833 | || kind == sfk_move_constructor || kind == sfk_inheriting_constructor) |
3046c0a3 | 1834 | DECL_CONSTRUCTOR_P (fn) = 1; |
1835 | else if (kind == sfk_destructor) | |
1836 | DECL_DESTRUCTOR_P (fn) = 1; | |
1837 | else | |
1838 | { | |
1839 | DECL_ASSIGNMENT_OPERATOR_P (fn) = 1; | |
1840 | SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR); | |
1841 | } | |
dda08454 | 1842 | |
1843 | DECL_ALIGN (fn) = MINIMUM_METHOD_BOUNDARY; | |
d94a3bb7 | 1844 | |
7873fcd6 | 1845 | /* Create the explicit arguments. */ |
3046c0a3 | 1846 | if (rhs_parm_type) |
1847 | { | |
1848 | /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we | |
1849 | want its type to be included in the mangled function | |
1850 | name. */ | |
b2e715d2 | 1851 | tree decl = cp_build_parm_decl (NULL_TREE, rhs_parm_type); |
1852 | TREE_READONLY (decl) = 1; | |
1853 | retrofit_lang_decl (decl); | |
1854 | DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1; | |
1855 | DECL_ARGUMENTS (fn) = decl; | |
3046c0a3 | 1856 | } |
fa6e8832 | 1857 | else if (kind == sfk_inheriting_constructor) |
1858 | { | |
1859 | tree *p = &DECL_ARGUMENTS (fn); | |
9ffa15ef | 1860 | int index = 1; |
fa6e8832 | 1861 | for (tree parm = inherited_parms; parm != void_list_node; |
1862 | parm = TREE_CHAIN (parm)) | |
1863 | { | |
1864 | *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm)); | |
9ffa15ef | 1865 | retrofit_lang_decl (*p); |
1866 | DECL_PARM_LEVEL (*p) = 1; | |
1867 | DECL_PARM_INDEX (*p) = index++; | |
fa6e8832 | 1868 | DECL_CONTEXT (*p) = fn; |
1869 | p = &DECL_CHAIN (*p); | |
1870 | } | |
1871 | SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base); | |
1872 | DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor); | |
1873 | /* A constructor so declared has the same access as the corresponding | |
1874 | constructor in X. */ | |
1875 | TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor); | |
1876 | TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor); | |
1877 | /* Copy constexpr from the inherited constructor even if the | |
1878 | inheriting constructor doesn't satisfy the requirements. */ | |
2d791ea6 | 1879 | constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor); |
fa6e8832 | 1880 | } |
074ab442 | 1881 | /* Add the "this" parameter. */ |
7873fcd6 | 1882 | this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED); |
1767a056 | 1883 | DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn); |
7873fcd6 | 1884 | DECL_ARGUMENTS (fn) = this_parm; |
cfb46e1f | 1885 | |
7873fcd6 | 1886 | grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL); |
3046c0a3 | 1887 | DECL_IN_AGGR_P (fn) = 1; |
ecdd3d84 | 1888 | DECL_ARTIFICIAL (fn) = 1; |
2336da2a | 1889 | DECL_DEFAULTED_FN (fn) = 1; |
60777f69 | 1890 | if (cxx_dialect >= cxx11) |
e8fa380d | 1891 | { |
fcc30b51 | 1892 | /* "The closure type associated with a lambda-expression has a deleted |
1893 | default constructor and a deleted copy assignment operator." */ | |
1894 | if ((kind == sfk_constructor | |
1895 | || kind == sfk_copy_assignment) | |
1896 | && LAMBDA_TYPE_P (type)) | |
1897 | deleted_p = true; | |
e8fa380d | 1898 | DECL_DELETED_FN (fn) = deleted_p; |
1899 | DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p; | |
1900 | } | |
b4f6d117 | 1901 | DECL_EXTERNAL (fn) = true; |
cfb46e1f | 1902 | DECL_NOT_REALLY_EXTERN (fn) = 1; |
d3981643 | 1903 | DECL_DECLARED_INLINE_P (fn) = 1; |
977e64ea | 1904 | set_linkage_according_to_type (type, fn); |
8b2942f7 | 1905 | if (TREE_PUBLIC (fn)) |
1906 | DECL_COMDAT (fn) = 1; | |
977e64ea | 1907 | rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); |
092b1d6f | 1908 | gcc_assert (!TREE_USED (fn)); |
ed36f1cf | 1909 | |
56c12fd4 | 1910 | /* Propagate constraints from the inherited constructor. */ |
1911 | if (flag_concepts && inherited_ctor) | |
1912 | if (tree orig_ci = get_constraints (inherited_ctor)) | |
1913 | { | |
1914 | tree new_ci = copy_node (orig_ci); | |
1915 | set_constraints (fn, new_ci); | |
1916 | } | |
1917 | ||
8223a66b | 1918 | /* Restore PROCESSING_TEMPLATE_DECL. */ |
1919 | processing_template_decl = saved_processing_template_decl; | |
1920 | ||
fa6e8832 | 1921 | if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL) |
1922 | fn = add_inherited_template_parms (fn, inherited_ctor); | |
1923 | ||
ecb10e6a | 1924 | /* Warn about calling a non-trivial move assignment in a virtual base. */ |
1925 | if (kind == sfk_move_assignment && !deleted_p && !trivial_p | |
1926 | && CLASSTYPE_VBASECLASSES (type)) | |
1927 | { | |
1928 | location_t loc = input_location; | |
1929 | input_location = DECL_SOURCE_LOCATION (fn); | |
1930 | synthesized_method_walk (type, kind, const_p, | |
1931 | NULL, NULL, NULL, NULL, true, | |
1932 | NULL_TREE, NULL_TREE); | |
1933 | input_location = loc; | |
1934 | } | |
1935 | ||
cfb46e1f | 1936 | return fn; |
1937 | } | |
dcbeb3ef | 1938 | |
e8c9f615 | 1939 | /* Gives any errors about defaulted functions which need to be deferred |
1940 | until the containing class is complete. */ | |
1941 | ||
1942 | void | |
1943 | defaulted_late_check (tree fn) | |
1944 | { | |
1945 | /* Complain about invalid signature for defaulted fn. */ | |
1946 | tree ctx = DECL_CONTEXT (fn); | |
1947 | special_function_kind kind = special_function_p (fn); | |
1948 | bool fn_const_p = (copy_fn_p (fn) == 2); | |
fa6e8832 | 1949 | tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p, |
1950 | NULL, NULL); | |
36ad1400 | 1951 | tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); |
e8c9f615 | 1952 | |
1953 | if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)), | |
1954 | TREE_TYPE (TREE_TYPE (implicit_fn))) | |
1955 | || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), | |
1956 | TYPE_ARG_TYPES (TREE_TYPE (implicit_fn)))) | |
1957 | { | |
1958 | error ("defaulted declaration %q+D", fn); | |
1959 | error_at (DECL_SOURCE_LOCATION (fn), | |
1960 | "does not match expected signature %qD", implicit_fn); | |
1961 | } | |
7b8358cf | 1962 | |
36ad1400 | 1963 | /* 8.4.2/2: An explicitly-defaulted function (...) may have an explicit |
1964 | exception-specification only if it is compatible (15.4) with the | |
1965 | exception-specification on the implicit declaration. If a function | |
1966 | is explicitly defaulted on its first declaration, (...) it is | |
7b8358cf | 1967 | implicitly considered to have the same exception-specification as if |
1968 | it had been implicitly declared. */ | |
3b9e7f06 | 1969 | maybe_instantiate_noexcept (fn); |
f2c1aabc | 1970 | tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); |
1971 | if (!fn_spec) | |
7b8358cf | 1972 | { |
f2c1aabc | 1973 | if (DECL_DEFAULTED_IN_CLASS_P (fn)) |
1974 | TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); | |
1975 | } | |
1976 | else if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec)) | |
1977 | /* Equivalent to the implicit spec. */; | |
1978 | else if (DECL_DEFAULTED_IN_CLASS_P (fn) | |
1979 | && !CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) | |
1980 | /* We can't compare an explicit exception-specification on a | |
1981 | constructor defaulted in the class body to the implicit | |
1982 | exception-specification until after we've parsed any NSDMI; see | |
1983 | after_nsdmi_defaulted_late_checks. */; | |
1984 | else | |
1985 | { | |
1986 | tree eh_spec = get_defaulted_eh_spec (fn); | |
1987 | if (!comp_except_specs (fn_spec, eh_spec, ce_normal)) | |
3239620b | 1988 | { |
36ad1400 | 1989 | if (DECL_DEFAULTED_IN_CLASS_P (fn)) |
f2c1aabc | 1990 | DECL_DELETED_FN (fn) = true; |
36ad1400 | 1991 | else |
1992 | error ("function %q+D defaulted on its redeclaration " | |
1993 | "with an exception-specification that differs from " | |
f2c1aabc | 1994 | "the implicit exception-specification %qX", fn, eh_spec); |
3239620b | 1995 | } |
36ad1400 | 1996 | } |
36ad1400 | 1997 | |
1998 | if (DECL_DEFAULTED_IN_CLASS_P (fn) | |
1999 | && DECL_DECLARED_CONSTEXPR_P (implicit_fn)) | |
2000 | { | |
2001 | /* Hmm...should we do this for out-of-class too? Should it be OK to | |
2002 | add constexpr later like inline, rather than requiring | |
2003 | declarations to match? */ | |
2004 | DECL_DECLARED_CONSTEXPR_P (fn) = true; | |
2005 | if (kind == sfk_constructor) | |
2006 | TYPE_HAS_CONSTEXPR_CTOR (ctx) = true; | |
e8fa380d | 2007 | } |
2008 | ||
2009 | if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn) | |
2010 | && DECL_DECLARED_CONSTEXPR_P (fn)) | |
2011 | { | |
2012 | if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) | |
262c8920 | 2013 | { |
2014 | error ("explicitly defaulted function %q+D cannot be declared " | |
2015 | "as constexpr because the implicit declaration is not " | |
2016 | "constexpr:", fn); | |
2017 | explain_implicit_non_constexpr (fn); | |
2018 | } | |
e8fa380d | 2019 | DECL_DECLARED_CONSTEXPR_P (fn) = false; |
7b8358cf | 2020 | } |
2ee92e27 | 2021 | |
2022 | if (DECL_DELETED_FN (implicit_fn)) | |
2023 | DECL_DELETED_FN (fn) = 1; | |
e8c9f615 | 2024 | } |
2025 | ||
f2c1aabc | 2026 | /* OK, we've parsed the NSDMI for class T, now we can check any explicit |
2027 | exception-specifications on functions defaulted in the class body. */ | |
2028 | ||
2029 | void | |
2030 | after_nsdmi_defaulted_late_checks (tree t) | |
2031 | { | |
2032 | if (uses_template_parms (t)) | |
2033 | return; | |
2034 | if (t == error_mark_node) | |
2035 | return; | |
2036 | for (tree fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) | |
2037 | if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn)) | |
2038 | { | |
2039 | tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); | |
2040 | if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec)) | |
2041 | continue; | |
2042 | ||
2043 | tree eh_spec = get_defaulted_eh_spec (fn); | |
2044 | if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)), | |
2045 | eh_spec, ce_normal)) | |
2046 | DECL_DELETED_FN (fn) = true; | |
2047 | } | |
2048 | } | |
2049 | ||
e8c9f615 | 2050 | /* Returns true iff FN can be explicitly defaulted, and gives any |
2051 | errors if defaulting FN is ill-formed. */ | |
2052 | ||
2053 | bool | |
2054 | defaultable_fn_check (tree fn) | |
2055 | { | |
2056 | special_function_kind kind = sfk_none; | |
2057 | ||
b944db44 | 2058 | if (template_parm_scope_p ()) |
2059 | { | |
2060 | error ("a template cannot be defaulted"); | |
2061 | return false; | |
2062 | } | |
2063 | ||
e8c9f615 | 2064 | if (DECL_CONSTRUCTOR_P (fn)) |
2065 | { | |
2066 | if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node) | |
2067 | kind = sfk_constructor; | |
2068 | else if (copy_fn_p (fn) > 0 | |
2069 | && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn)) | |
2070 | == void_list_node)) | |
2071 | kind = sfk_copy_constructor; | |
2072 | else if (move_fn_p (fn)) | |
2073 | kind = sfk_move_constructor; | |
2074 | } | |
2075 | else if (DECL_DESTRUCTOR_P (fn)) | |
2076 | kind = sfk_destructor; | |
2077 | else if (DECL_ASSIGNMENT_OPERATOR_P (fn) | |
2ee92e27 | 2078 | && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) |
2079 | { | |
2080 | if (copy_fn_p (fn)) | |
2081 | kind = sfk_copy_assignment; | |
2082 | else if (move_fn_p (fn)) | |
2083 | kind = sfk_move_assignment; | |
2084 | } | |
e8c9f615 | 2085 | |
2086 | if (kind == sfk_none) | |
2087 | { | |
2088 | error ("%qD cannot be defaulted", fn); | |
2089 | return false; | |
2090 | } | |
2091 | else | |
2092 | { | |
eb1cea71 | 2093 | for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn); |
2094 | t && t != void_list_node; t = TREE_CHAIN (t)) | |
e8c9f615 | 2095 | if (TREE_PURPOSE (t)) |
2096 | { | |
2097 | error ("defaulted function %q+D with default argument", fn); | |
2098 | break; | |
2099 | } | |
eb1cea71 | 2100 | |
2101 | /* Avoid do_warn_unused_parameter warnings. */ | |
2102 | for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p)) | |
2103 | if (DECL_NAME (p)) | |
2104 | TREE_NO_WARNING (p) = 1; | |
2105 | ||
e8c9f615 | 2106 | if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn))) |
fd3ee139 | 2107 | /* Defer checking. */; |
e8c9f615 | 2108 | else if (!processing_template_decl) |
2109 | defaulted_late_check (fn); | |
2110 | ||
2111 | return true; | |
2112 | } | |
2113 | } | |
2114 | ||
1827796b | 2115 | /* Add an implicit declaration to TYPE for the kind of function |
2116 | indicated by SFK. Return the FUNCTION_DECL for the new implicit | |
2117 | declaration. */ | |
2118 | ||
2119 | tree | |
2120 | lazily_declare_fn (special_function_kind sfk, tree type) | |
2121 | { | |
2122 | tree fn; | |
2ee92e27 | 2123 | /* Whether or not the argument has a const reference type. */ |
2124 | bool const_p = false; | |
2125 | ||
041558e3 | 2126 | type = TYPE_MAIN_VARIANT (type); |
2127 | ||
2ee92e27 | 2128 | switch (sfk) |
2129 | { | |
2130 | case sfk_constructor: | |
2131 | CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0; | |
2132 | break; | |
2133 | case sfk_copy_constructor: | |
2134 | const_p = TYPE_HAS_CONST_COPY_CTOR (type); | |
2135 | CLASSTYPE_LAZY_COPY_CTOR (type) = 0; | |
2136 | break; | |
2137 | case sfk_move_constructor: | |
2138 | CLASSTYPE_LAZY_MOVE_CTOR (type) = 0; | |
2139 | break; | |
2140 | case sfk_copy_assignment: | |
2141 | const_p = TYPE_HAS_CONST_COPY_ASSIGN (type); | |
2142 | CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0; | |
2143 | break; | |
2144 | case sfk_move_assignment: | |
2145 | CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0; | |
2146 | break; | |
2147 | case sfk_destructor: | |
2148 | CLASSTYPE_LAZY_DESTRUCTOR (type) = 0; | |
2149 | break; | |
2150 | default: | |
2151 | gcc_unreachable (); | |
2152 | } | |
2153 | ||
1827796b | 2154 | /* Declare the function. */ |
fa6e8832 | 2155 | fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL); |
2ee92e27 | 2156 | |
b68e6235 | 2157 | /* [class.copy]/8 If the class definition declares a move constructor or |
2158 | move assignment operator, the implicitly declared copy constructor is | |
2159 | defined as deleted.... */ | |
2160 | if ((sfk == sfk_copy_assignment | |
2161 | || sfk == sfk_copy_constructor) | |
2162 | && (type_has_user_declared_move_constructor (type) | |
2163 | || type_has_user_declared_move_assign (type))) | |
2164 | DECL_DELETED_FN (fn) = true; | |
2165 | ||
ed36f1cf | 2166 | /* A destructor may be virtual. */ |
523ff179 | 2167 | if (sfk == sfk_destructor |
2ee92e27 | 2168 | || sfk == sfk_move_assignment |
ab8002de | 2169 | || sfk == sfk_copy_assignment) |
ed36f1cf | 2170 | check_for_override (fn, type); |
1827796b | 2171 | /* Add it to CLASSTYPE_METHOD_VEC. */ |
49213a81 | 2172 | add_method (type, fn, NULL_TREE); |
1827796b | 2173 | /* Add it to TYPE_METHODS. */ |
9031d10b | 2174 | if (sfk == sfk_destructor |
f591db9a | 2175 | && DECL_VIRTUAL_P (fn)) |
ed36f1cf | 2176 | /* The ABI requires that a virtual destructor go at the end of the |
2177 | vtable. */ | |
2178 | TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn); | |
2179 | else | |
2180 | { | |
1767a056 | 2181 | DECL_CHAIN (fn) = TYPE_METHODS (type); |
ed36f1cf | 2182 | TYPE_METHODS (type) = fn; |
2183 | } | |
1827796b | 2184 | maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); |
2ee92e27 | 2185 | if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) |
2186 | || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) | |
2187 | /* Create appropriate clones. */ | |
2188 | clone_function_decl (fn, /*update_method_vec=*/true); | |
1827796b | 2189 | |
2190 | return fn; | |
2191 | } | |
2192 | ||
dcbeb3ef | 2193 | /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST |
2194 | as there are artificial parms in FN. */ | |
2195 | ||
2196 | tree | |
9f627b1a | 2197 | skip_artificial_parms_for (const_tree fn, tree list) |
dcbeb3ef | 2198 | { |
2199 | if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) | |
2200 | list = TREE_CHAIN (list); | |
2201 | else | |
2202 | return list; | |
2203 | ||
2204 | if (DECL_HAS_IN_CHARGE_PARM_P (fn)) | |
2205 | list = TREE_CHAIN (list); | |
2206 | if (DECL_HAS_VTT_PARM_P (fn)) | |
2207 | list = TREE_CHAIN (list); | |
2208 | return list; | |
2209 | } | |
d7bec695 | 2210 | |
d01f58f9 | 2211 | /* Given a FUNCTION_DECL FN and a chain LIST, return the number of |
2212 | artificial parms in FN. */ | |
2213 | ||
2214 | int | |
9f627b1a | 2215 | num_artificial_parms_for (const_tree fn) |
d01f58f9 | 2216 | { |
2217 | int count = 0; | |
2218 | ||
2219 | if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) | |
2220 | count++; | |
2221 | else | |
2222 | return 0; | |
2223 | ||
2224 | if (DECL_HAS_IN_CHARGE_PARM_P (fn)) | |
2225 | count++; | |
2226 | if (DECL_HAS_VTT_PARM_P (fn)) | |
2227 | count++; | |
2228 | return count; | |
2229 | } | |
2230 | ||
2231 | ||
d7bec695 | 2232 | #include "gt-cp-method.h" |