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