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