]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/except.c
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / except.c
CommitLineData
8d08fdba 1/* Handle exceptional things in C++.
7adcbafe 2 Copyright (C) 1989-2022 Free Software Foundation, Inc.
8d2733ca
MS
3 Contributed by Michael Tiemann <tiemann@cygnus.com>
4 Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
5 initial re-implementation courtesy Tad Hunt.
8d08fdba 6
f5adbb8d 7This file is part of GCC.
8d08fdba 8
f5adbb8d 9GCC is free software; you can redistribute it and/or modify
8d08fdba 10it under the terms of the GNU General Public License as published by
e77f031d 11the Free Software Foundation; either version 3, or (at your option)
8d08fdba
MS
12any later version.
13
f5adbb8d 14GCC is distributed in the hope that it will be useful,
8d08fdba
MS
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
e77f031d
NC
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
8d08fdba
MS
22
23
8d08fdba 24#include "config.h"
8d052bc7 25#include "system.h"
4977bab6 26#include "coretypes.h"
2adfab87 27#include "cp-tree.h"
d8a2d370
DN
28#include "stringpool.h"
29#include "trans-mem.h"
30#include "attribs.h"
325c3691 31#include "tree-iterator.h"
02a32ab4 32#include "target.h"
8d08fdba 33
5cc3d3b8
GDR
34static void push_eh_cleanup (tree);
35static tree prepare_eh_type (tree);
5cc3d3b8
GDR
36static tree do_begin_catch (void);
37static int dtor_nothrow (tree);
38static tree do_end_catch (tree);
5cc3d3b8
GDR
39static void initialize_handler_parm (tree, tree);
40static tree do_allocate_exception (tree);
5cc3d3b8
GDR
41static tree wrap_cleanups_r (tree *, int *, void *);
42static int complete_ptr_ref_or_void_ptr_p (tree, tree);
f9eead1f 43static bool is_admissible_throw_operand_or_catch_parameter (tree, bool);
8d2733ca 44
52a11cbf 45/* Sets up all the global eh stuff that needs to be initialized at the
bbd0d54a 46 start of compilation. */
8d08fdba 47
8d08fdba 48void
5cc3d3b8 49init_exception_processing (void)
8d08fdba 50{
52a11cbf
RH
51 tree tmp;
52
52a11cbf 53 /* void std::terminate (); */
5a7c4505 54 push_nested_namespace (std_node);
0244e6f7 55 tmp = build_function_type_list (void_type_node, NULL_TREE);
1a66d857 56 terminate_fn = build_cp_library_fn_ptr ("terminate", tmp,
cb59f689
JH
57 ECF_NOTHROW | ECF_NORETURN
58 | ECF_COLD);
59 gcc_checking_assert (TREE_THIS_VOLATILE (terminate_fn)
60 && TREE_NOTHROW (terminate_fn));
5a7c4505 61 pop_nested_namespace (std_node);
8ccc31eb 62
52a11cbf 63 /* void __cxa_call_unexpected(void *); */
0244e6f7 64 tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1a66d857 65 call_unexpected_fn
52a11cbf 66 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
6874c264
JM
67}
68
e6855a2d 69/* Returns an expression to be executed if an unhandled exception is
aba649ba 70 propagated out of a cleanup region. */
e6855a2d 71
3b06d379 72tree
5cc3d3b8 73cp_protect_cleanup_actions (void)
e6855a2d
MM
74{
75 /* [except.terminate]
76
77 When the destruction of an object during stack unwinding exits
78 using an exception ... void terminate(); is called. */
1a66d857 79 return terminate_fn;
c8094d83 80}
e6855a2d 81
6874c264 82static tree
5cc3d3b8 83prepare_eh_type (tree type)
8d08fdba 84{
52a11cbf
RH
85 if (type == NULL_TREE)
86 return type;
f30432d7
MS
87 if (type == error_mark_node)
88 return error_mark_node;
8d2733ca 89
e92cc029 90 /* peel back references, so they match. */
ee76b931 91 type = non_reference (type);
8d08fdba 92
e92cc029 93 /* Peel off cv qualifiers. */
f30432d7 94 type = TYPE_MAIN_VARIANT (type);
8d2733ca 95
86ef5ebb
JM
96 /* Functions and arrays decay to pointers. */
97 type = type_decays_to (type);
98
52a11cbf 99 return type;
8d08fdba 100}
8d08fdba 101
6cad4e17
JH
102/* Return the type info for TYPE as used by EH machinery. */
103tree
104eh_type_info (tree type)
5816cb14 105{
93ca4ba7
JM
106 if (type == NULL_TREE || type == error_mark_node)
107 return type;
5816cb14 108
bfecd57c 109 return get_tinfo_decl (type);
5816cb14
AM
110}
111
6cad4e17
JH
112/* Build the address of a typeinfo decl for use in the runtime
113 matching field of the exception model. */
114
f9417da1 115tree
6cad4e17
JH
116build_eh_type_type (tree type)
117{
118 tree exp = eh_type_info (type);
119
120 if (!exp)
121 return NULL;
122
f820b0cf
JH
123 mark_used (exp);
124
6de9cd9a 125 return convert (ptr_type_node, build_address (exp));
6cad4e17
JH
126}
127
52a11cbf 128tree
5cc3d3b8 129build_exc_ptr (void)
52a11cbf 130{
e79983f4 131 return build_call_n (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1d65f45c 132 1, integer_zero_node);
52a11cbf
RH
133}
134
e88218fd
NS
135/* Declare an exception ABI entry point called NAME.
136 ECF are the library flags, RTYPE the return type and ARGS[NARGS]
137 the parameter types. We return the DECL -- which might be one
138 found via the symbol table pushing, if the user already declared
139 it. If we pushed a new decl, the user will see it. */
784417d1 140
e88218fd
NS
141static tree
142declare_library_fn_1 (const char *name, int ecf,
143 tree rtype, int nargs, tree args[])
784417d1 144{
e88218fd
NS
145 tree ident = get_identifier (name);
146 tree except = ecf & ECF_NOTHROW ? empty_except_spec : NULL_TREE;
147
148 /* Make a new decl. */
149 tree arg_list = void_list_node;
150 for (unsigned ix = nargs; ix--;)
151 arg_list = tree_cons (NULL_TREE, args[ix], arg_list);
152 tree fntype = build_function_type (rtype, arg_list);
153 tree res = push_library_fn (ident, fntype, except, ecf);
154
155 return res;
784417d1
JJ
156}
157
1a66d857
NS
158/* Find or declare a function NAME, returning RTYPE, taking a single
159 parameter PTYPE, with an empty exception specification. ECF are the
160 library fn flags. If TM_ECF is non-zero, also find or create a
161 transaction variant and record it as a replacement, when flag_tm is
162 in effect.
448083e5
PC
163
164 Note that the C++ ABI document does not have a throw-specifier on
165 the routines declared below via this function. The declarations
166 are consistent with the actual implementations in libsupc++. */
167
168static tree
1a66d857
NS
169declare_library_fn (const char *name, tree rtype, tree ptype,
170 int ecf, int tm_ecf)
448083e5 171{
e88218fd
NS
172 tree res = declare_library_fn_1 (name, ecf, rtype, ptype ? 1 : 0, &ptype);
173 if (res == error_mark_node)
174 return res;
784417d1
JJ
175
176 if (tm_ecf && flag_tm)
177 {
178 char *tm_name = concat ("_ITM_", name + 2, NULL_TREE);
e88218fd
NS
179
180 tree tm_fn = declare_library_fn_1 (tm_name, ecf | tm_ecf, rtype,
181 ptype ? 1 : 0, &ptype);
784417d1
JJ
182 free (tm_name);
183 if (tm_fn != error_mark_node)
184 record_tm_replacement (res, tm_fn);
1a66d857 185 }
e88218fd 186
1a66d857 187 return res;
448083e5
PC
188}
189
39609077
RH
190/* Build up a call to __cxa_get_exception_ptr so that we can build a
191 copy constructor for the thrown object. */
192
193static tree
194do_get_exception_ptr (void)
195{
1a66d857
NS
196 if (!get_exception_ptr_fn)
197 /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
198 get_exception_ptr_fn
199 = declare_library_fn ("__cxa_get_exception_ptr",
200 ptr_type_node, ptr_type_node,
201 ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE,
202 0);
203
204 return cp_build_function_call_nary (get_exception_ptr_fn,
205 tf_warning_or_error,
450f4293 206 build_exc_ptr (), NULL_TREE);
39609077
RH
207}
208
52a11cbf
RH
209/* Build up a call to __cxa_begin_catch, to tell the runtime that the
210 exception has been handled. */
93ca4ba7 211
52a11cbf 212static tree
5cc3d3b8 213do_begin_catch (void)
9c606f69 214{
1a66d857
NS
215 if (!begin_catch_fn)
216 /* Declare void* __cxa_begin_catch (void *) throw(). */
217 begin_catch_fn
218 = declare_library_fn ("__cxa_begin_catch",
219 ptr_type_node, ptr_type_node, ECF_NOTHROW,
220 ECF_TM_PURE);
221
222 return cp_build_function_call_nary (begin_catch_fn, tf_warning_or_error,
450f4293 223 build_exc_ptr (), NULL_TREE);
9c606f69
AM
224}
225
93ca4ba7
JM
226/* Returns nonzero if cleaning up an exception of type TYPE (which can be
227 NULL_TREE for a ... handler) will not throw an exception. */
228
229static int
5cc3d3b8 230dtor_nothrow (tree type)
93ca4ba7 231{
9bb1a81b 232 if (type == NULL_TREE || type == error_mark_node)
93ca4ba7
JM
233 return 0;
234
9bb1a81b 235 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
93ca4ba7
JM
236 return 1;
237
9f4faeae
MM
238 if (CLASSTYPE_LAZY_DESTRUCTOR (type))
239 lazily_declare_fn (sfk_destructor, type);
240
b2cf76f3 241 return TREE_NOTHROW (CLASSTYPE_DESTRUCTOR (type));
93ca4ba7
JM
242}
243
52a11cbf 244/* Build up a call to __cxa_end_catch, to destroy the exception object
93ca4ba7 245 for the current catch block if no others are currently using it. */
6467930b 246
c7ae64f2 247static tree
5cc3d3b8 248do_end_catch (tree type)
72b7eeff 249{
1a66d857
NS
250 if (!end_catch_fn)
251 /* Declare void __cxa_end_catch ().
252 This can throw if the destructor for the exception throws. */
253 end_catch_fn
254 = declare_library_fn ("__cxa_end_catch", void_type_node,
255 NULL_TREE, 0, ECF_TM_PURE);
256
257 tree cleanup = cp_build_function_call_vec (end_catch_fn,
258 NULL, tf_warning_or_error);
784417d1
JJ
259 if (cleanup != error_mark_node)
260 TREE_NOTHROW (cleanup) = dtor_nothrow (type);
52a11cbf 261
c0700ea5 262 return cleanup;
c7ae64f2
JM
263}
264
265/* This routine creates the cleanup for the current exception. */
72b7eeff 266
c7ae64f2 267static void
5cc3d3b8 268push_eh_cleanup (tree type)
c7ae64f2 269{
52a11cbf 270 finish_decl_cleanup (NULL_TREE, do_end_catch (type));
f4a23343
JM
271}
272
f2162c3d
TR
273/* Wrap EXPR in a MUST_NOT_THROW_EXPR expressing that EXPR must
274 not throw any exceptions if COND is true. A condition of
275 NULL_TREE is treated as 'true'. */
276
277tree
278build_must_not_throw_expr (tree body, tree cond)
279{
280 tree type = body ? TREE_TYPE (body) : void_type_node;
281
6df2ca09
TV
282 if (!flag_exceptions)
283 return body;
284
a0ab7ccd
JM
285 if (!cond)
286 /* OK, unconditional. */;
287 else
f2162c3d 288 {
a0ab7ccd
JM
289 tree conv = NULL_TREE;
290 if (!type_dependent_expression_p (cond))
291 conv = perform_implicit_conversion_flags (boolean_type_node, cond,
292 tf_warning_or_error,
293 LOOKUP_NORMAL);
294 if (tree inst = instantiate_non_dependent_or_null (conv))
295 cond = cxx_constant_value (inst);
296 else
297 require_constant_expression (cond);
f2162c3d
TR
298 if (integer_zerop (cond))
299 return body;
300 else if (integer_onep (cond))
301 cond = NULL_TREE;
302 }
303
304 return build2 (MUST_NOT_THROW_EXPR, type, body, cond);
305}
306
307
b35d4555 308/* Initialize the catch parameter DECL. */
6467930b 309
c8094d83 310static void
5cc3d3b8 311initialize_handler_parm (tree decl, tree exp)
8d08fdba 312{
b35d4555
MM
313 tree init;
314 tree init_type;
315
316 /* Make sure we mark the catch param as used, otherwise we'll get a
317 warning about an unused ((anonymous)). */
318 TREE_USED (decl) = 1;
03a904b5 319 DECL_READ_P (decl) = 1;
b35d4555 320
52a11cbf 321 /* Figure out the type that the initializer is. Pointers are returned
c8094d83 322 adjusted by value from __cxa_begin_catch. Others are returned by
52a11cbf 323 reference. */
b35d4555 324 init_type = TREE_TYPE (decl);
71a93b08 325 if (!INDIRECT_TYPE_P (init_type))
b35d4555
MM
326 init_type = build_reference_type (init_type);
327
b35d4555 328 /* Since pointers are passed by value, initialize a reference to
52a11cbf 329 pointer catch parm with the address of the temporary. */
9f613f06 330 if (TYPE_REF_P (init_type)
c93586fa 331 && TYPE_PTR_P (TREE_TYPE (init_type)))
93c0e0bb 332 exp = cp_build_addr_expr (exp, tf_warning_or_error);
b35d4555 333
4b978f96
PC
334 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
335 tf_warning_or_error);
b35d4555
MM
336
337 init = convert_from_reference (exp);
338
339 /* If the constructor for the catch parm exits via an exception, we
340 must call terminate. See eh23.C. */
341 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
faf5394a 342 {
b35d4555
MM
343 /* Generate the copy constructor call directly so we can wrap it.
344 See also expand_default_init. */
345 init = ocp_convert (TREE_TYPE (decl), init,
4b978f96
PC
346 CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
347 tf_warning_or_error);
ba6c89a9
JM
348 /* Force cleanups now to avoid nesting problems with the
349 MUST_NOT_THROW_EXPR. */
c1bb7f86 350 init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
f2162c3d 351 init = build_must_not_throw_expr (init, NULL_TREE);
faf5394a
MS
352 }
353
b35d4555 354 decl = pushdecl (decl);
8d2733ca 355
e92fb501 356 start_decl_1 (decl, true);
d174af6c 357 cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
b35d4555 358 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
5816cb14
AM
359}
360
3b06d379
SB
361\f
362/* Routine to see if exception handling is turned on.
363 DO_WARN is nonzero if we want to inform the user that exception
364 handling is turned off.
365
366 This is used to ensure that -fexceptions has been specified if the
367 compiler tries to use any exception-specific functions. */
368
369static inline int
370doing_eh (void)
371{
372 if (! flag_exceptions)
373 {
374 static int warned = 0;
375 if (! warned)
376 {
a3f9f006 377 error ("exception handling disabled, use %<-fexceptions%> to enable");
3b06d379
SB
378 warned = 1;
379 }
380 return 0;
381 }
382 return 1;
383}
384
b35d4555 385/* Call this to start a catch block. DECL is the catch parameter. */
5816cb14 386
b35d4555 387tree
5cc3d3b8 388expand_start_catch_block (tree decl)
5816cb14 389{
39609077 390 tree exp;
4227d4a1 391 tree type, init;
5816cb14 392
3b06d379 393 if (! doing_eh ())
b35d4555 394 return NULL_TREE;
5816cb14 395
52a11cbf 396 if (decl)
f9eead1f
PC
397 {
398 if (!is_admissible_throw_operand_or_catch_parameter (decl, false))
399 decl = error_mark_node;
400
401 type = prepare_eh_type (TREE_TYPE (decl));
785b887e 402 mark_used (eh_type_info (type));
f9eead1f 403 }
52a11cbf
RH
404 else
405 type = NULL_TREE;
52a11cbf 406
39609077
RH
407 /* Call __cxa_end_catch at the end of processing the exception. */
408 push_eh_cleanup (type);
409
4227d4a1
PC
410 init = do_begin_catch ();
411
39609077
RH
412 /* If there's no decl at all, then all we need to do is make sure
413 to tell the runtime that we've begun handling the exception. */
4227d4a1
PC
414 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
415 finish_expr_stmt (init);
39609077
RH
416
417 /* If the C++ object needs constructing, we need to do that before
418 calling __cxa_begin_catch, so that std::uncaught_exception gets
419 the right value during the copy constructor. */
3db45ab5 420 else if (flag_use_cxa_get_exception_ptr
c7b5e395 421 && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
39609077
RH
422 {
423 exp = do_get_exception_ptr ();
784417d1
JJ
424 if (exp != error_mark_node)
425 initialize_handler_parm (decl, exp);
4227d4a1 426 finish_expr_stmt (init);
39609077
RH
427 }
428
429 /* Otherwise the type uses a bitwise copy, and we don't have to worry
430 about the value of std::uncaught_exception and therefore can do the
431 copy with the return value of __cxa_end_catch instead. */
432 else
433 {
2de9107a
R
434 tree init_type = type;
435
436 /* Pointers are passed by values, everything else by reference. */
437 if (!TYPE_PTR_P (type))
438 init_type = build_pointer_type (type);
439 if (init_type != TREE_TYPE (init))
440 init = build1 (NOP_EXPR, init_type, init);
441 exp = create_temporary_var (init_type);
3db45ab5 442 cp_finish_decl (exp, init, /*init_const_expr=*/false,
d174af6c 443 NULL_TREE, LOOKUP_ONLYCONVERTING);
a2c6e7f2 444 DECL_REGISTER (exp) = 1;
39609077 445 initialize_handler_parm (decl, exp);
e97f22c9 446 }
5816cb14 447
1a6025b4 448 return type;
5816cb14
AM
449}
450
f30432d7 451
8d2733ca
MS
452/* Call this to end a catch block. Its responsible for emitting the
453 code to handle jumping back to the correct place, and for emitting
454 the label to jump to if this catch block didn't match. */
6467930b 455
824b9a4c 456void
5cc3d3b8 457expand_end_catch_block (void)
8d08fdba 458{
3b06d379 459 if (! doing_eh ())
f30432d7 460 return;
8d2733ca 461
0dde4175
JM
462 /* The exception being handled is rethrown if control reaches the end of
463 a handler of the function-try-block of a constructor or destructor. */
464 if (in_function_try_handler
465 && (DECL_CONSTRUCTOR_P (current_function_decl)
466 || DECL_DESTRUCTOR_P (current_function_decl)))
8243e2a9 467 {
d3769410 468 tree rethrow = build_throw (input_location, NULL_TREE);
65870e75
MS
469 /* Disable all warnings for the generated rethrow statement. */
470 suppress_warning (rethrow);
8243e2a9
JM
471 finish_expr_stmt (rethrow);
472 }
8d2733ca 473}
8d08fdba 474
b35d4555 475tree
5cc3d3b8 476begin_eh_spec_block (void)
f30432d7 477{
9feb3d6a 478 tree r;
e70e0b60
SP
479 location_t spec_location = DECL_SOURCE_LOCATION (current_function_decl);
480
9feb3d6a
JM
481 /* A noexcept specification (or throw() with -fnothrow-opt) is a
482 MUST_NOT_THROW_EXPR. */
483 if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl)))
484 {
f2162c3d
TR
485 r = build_stmt (spec_location, MUST_NOT_THROW_EXPR,
486 NULL_TREE, NULL_TREE);
9feb3d6a
JM
487 TREE_SIDE_EFFECTS (r) = 1;
488 }
489 else
e70e0b60 490 r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
52a11cbf 491 add_stmt (r);
9feb3d6a 492 TREE_OPERAND (r, 0) = push_stmt_list ();
52a11cbf 493 return r;
f30432d7
MS
494}
495
b35d4555 496void
5cc3d3b8 497finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
f30432d7 498{
52a11cbf 499 tree raises;
0c11ada6 500
9feb3d6a
JM
501 TREE_OPERAND (eh_spec_block, 0)
502 = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0));
503
504 if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR)
505 return;
6c20b7e9 506
52a11cbf
RH
507 /* Strip cv quals, etc, from the specification types. */
508 for (raises = NULL_TREE;
509 raw_raises && TREE_VALUE (raw_raises);
510 raw_raises = TREE_CHAIN (raw_raises))
6cad4e17
JH
511 {
512 tree type = prepare_eh_type (TREE_VALUE (raw_raises));
513 tree tinfo = eh_type_info (type);
514
515 mark_used (tinfo);
516 raises = tree_cons (NULL_TREE, type, raises);
517 }
6c20b7e9 518
52a11cbf 519 EH_SPEC_RAISES (eh_spec_block) = raises;
f30432d7
MS
520}
521
52a11cbf 522/* Return a pointer to a buffer for an exception object of type TYPE. */
6467930b 523
52a11cbf 524static tree
5cc3d3b8 525do_allocate_exception (tree type)
8d08fdba 526{
1a66d857
NS
527 if (!allocate_exception_fn)
528 /* Declare void *__cxa_allocate_exception(size_t) throw(). */
529 allocate_exception_fn
530 = declare_library_fn ("__cxa_allocate_exception",
531 ptr_type_node, size_type_node,
c3cc0122 532 ECF_NOTHROW | ECF_MALLOC | ECF_COLD, ECF_TM_PURE);
1a66d857
NS
533
534 return cp_build_function_call_nary (allocate_exception_fn,
535 tf_warning_or_error,
450f4293 536 size_in_bytes (type), NULL_TREE);
8d08fdba
MS
537}
538
2ac8a0f9 539/* Call __cxa_free_exception from a cleanup. This is never invoked
6f30f1f1 540 directly, but see the comment for stabilize_throw_expr. */
f4a23343 541
c6160f8f 542static tree
5cc3d3b8 543do_free_exception (tree ptr)
f4a23343 544{
1a66d857
NS
545 if (!free_exception_fn)
546 /* Declare void __cxa_free_exception (void *) throw(). */
547 free_exception_fn
548 = declare_library_fn ("__cxa_free_exception",
549 void_type_node, ptr_type_node,
550 ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE);
551
552 return cp_build_function_call_nary (free_exception_fn,
553 tf_warning_or_error, ptr, NULL_TREE);
f4a23343
JM
554}
555
6f30f1f1
JM
556/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
557 Called from build_throw via walk_tree_without_duplicates. */
558
559static tree
12308bc6 560wrap_cleanups_r (tree *tp, int *walk_subtrees, void * /*data*/)
6f30f1f1
JM
561{
562 tree exp = *tp;
563 tree cleanup;
564
565 /* Don't walk into types. */
566 if (TYPE_P (exp))
567 {
568 *walk_subtrees = 0;
569 return NULL_TREE;
570 }
571 if (TREE_CODE (exp) != TARGET_EXPR)
572 return NULL_TREE;
573
574 cleanup = TARGET_EXPR_CLEANUP (exp);
575 if (cleanup)
576 {
f2162c3d
TR
577 cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup,
578 NULL_TREE);
6f30f1f1
JM
579 TARGET_EXPR_CLEANUP (exp) = cleanup;
580 }
581
582 /* Keep iterating. */
583 return NULL_TREE;
584}
585
52a11cbf 586/* Build a throw expression. */
6467930b 587
52a11cbf 588tree
d3769410 589build_throw (location_t loc, tree exp)
8d08fdba 590{
52a11cbf
RH
591 if (exp == error_mark_node)
592 return exp;
593
594 if (processing_template_decl)
aff5c451 595 {
07515729
JJ
596 if (cfun)
597 current_function_returns_abnormally = 1;
73808ca6 598 exp = build_min (THROW_EXPR, void_type_node, exp);
d3769410 599 SET_EXPR_LOCATION (exp, loc);
73808ca6 600 return exp;
aff5c451 601 }
52a11cbf 602
9a004410 603 if (exp && null_node_p (exp))
d3769410
PC
604 warning_at (loc, 0,
605 "throwing NULL, which has integral, not pointer type");
c8094d83 606
52a11cbf
RH
607 if (exp != NULL_TREE)
608 {
f9eead1f 609 if (!is_admissible_throw_operand_or_catch_parameter (exp, true))
0cbd7506 610 return error_mark_node;
52a11cbf
RH
611 }
612
3b06d379 613 if (! doing_eh ())
59ccf49d 614 return error_mark_node;
8d08fdba 615
bfecd57c 616 if (exp)
8d2733ca 617 {
faae18ab 618 tree throw_type;
41990f96 619 tree temp_type;
52a11cbf 620 tree cleanup;
52a11cbf 621 tree object, ptr;
b33a0480 622 tree allocate_expr;
52a11cbf 623
fbac6f3c
MM
624 /* The CLEANUP_TYPE is the internal type of a destructor. */
625 if (!cleanup_type)
626 {
e88218fd
NS
627 tree tmp = build_function_type_list (void_type_node,
628 ptr_type_node, NULL_TREE);
fbac6f3c
MM
629 cleanup_type = build_pointer_type (tmp);
630 }
c8094d83 631
4b4b2e58 632 if (!throw_fn)
52a11cbf 633 {
e88218fd 634 tree args[3] = {ptr_type_node, ptr_type_node, cleanup_type};
4b4b2e58 635
e88218fd
NS
636 throw_fn = declare_library_fn_1 ("__cxa_throw",
637 ECF_NORETURN | ECF_COLD,
638 void_type_node, 3, args);
784417d1
JJ
639 if (flag_tm && throw_fn != error_mark_node)
640 {
e88218fd
NS
641 tree itm_fn = declare_library_fn_1 ("_ITM_cxa_throw",
642 ECF_NORETURN | ECF_COLD,
643 void_type_node, 3, args);
784417d1 644 if (itm_fn != error_mark_node)
4b4b2e58 645 {
4b4b2e58
NS
646 apply_tm_attr (itm_fn, get_identifier ("transaction_pure"));
647 record_tm_replacement (throw_fn, itm_fn);
648 }
0a35513e 649 }
52a11cbf 650 }
c8094d83 651
3db45ab5
MS
652 /* [except.throw]
653
654 A throw-expression initializes a temporary object, the type
41990f96
MM
655 of which is determined by removing any top-level
656 cv-qualifiers from the static type of the operand of throw
657 and adjusting the type from "array of T" or "function return
658 T" to "pointer to T" or "pointer to function returning T"
659 respectively. */
660 temp_type = is_bitfield_expr_with_lowered_type (exp);
661 if (!temp_type)
ccaff498 662 temp_type = cv_unqualified (type_decays_to (TREE_TYPE (exp)));
a3b49ccd 663
52a11cbf
RH
664 /* OK, this is kind of wacky. The standard says that we call
665 terminate when the exception handling mechanism, after
666 completing evaluation of the expression to be thrown but
667 before the exception is caught (_except.throw_), calls a
668 user function that exits via an uncaught exception.
669
670 So we have to protect the actual initialization of the
671 exception object with terminate(), but evaluate the
672 expression first. Since there could be temps in the
673 expression, we need to handle that, too. We also expand
674 the call to __cxa_allocate_exception first (which doesn't
675 matter, since it can't throw). */
676
52a11cbf 677 /* Allocate the space for the exception. */
41990f96 678 allocate_expr = do_allocate_exception (temp_type);
784417d1
JJ
679 if (allocate_expr == error_mark_node)
680 return error_mark_node;
6f30f1f1
JM
681 allocate_expr = get_target_expr (allocate_expr);
682 ptr = TARGET_EXPR_SLOT (allocate_expr);
b33a0480
JM
683 TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr);
684 CLEANUP_EH_ONLY (allocate_expr) = 1;
685
41990f96 686 object = build_nop (build_pointer_type (temp_type), ptr);
04757a2a 687 object = cp_build_fold_indirect_ref (object);
faae18ab 688
6f30f1f1 689 /* And initialize the exception object. */
36cbfdb0 690 if (CLASS_TYPE_P (temp_type))
6f30f1f1 691 {
8af2fec4 692 int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
4ce8c5de 693 bool converted = false;
d3769410 694 location_t exp_loc = cp_expr_loc_or_loc (exp, loc);
8af2fec4
RY
695
696 /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
697 treated as an rvalue for the purposes of overload resolution
698 to favor move constructors over copy constructors. */
1722e201 699 if (tree moved = treat_lvalue_as_rvalue_p (exp, /*return*/false))
4ce8c5de 700 {
1722e201 701 if (cxx_dialect < cxx20)
4ce8c5de 702 {
1722e201
JM
703 releasing_vec exp_vec (make_tree_vector_single (moved));
704 moved = (build_special_member_call
705 (object, complete_ctor_identifier, &exp_vec,
706 TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE,
707 tf_none));
708 if (moved != error_mark_node)
709 {
710 exp = moved;
711 converted = true;
712 }
4ce8c5de 713 }
1722e201
JM
714 else
715 /* In C++20 we just treat the return value as an rvalue that
716 can bind to lvalue refs. */
717 exp = moved;
4ce8c5de 718 }
8af2fec4 719
41990f96 720 /* Call the copy constructor. */
4ce8c5de
JM
721 if (!converted)
722 {
cd9cf97b 723 releasing_vec exp_vec (make_tree_vector_single (exp));
4ce8c5de
JM
724 exp = (build_special_member_call
725 (object, complete_ctor_identifier, &exp_vec,
726 TREE_TYPE (object), flags, tf_warning_or_error));
4ce8c5de
JM
727 }
728
41990f96
MM
729 if (exp == error_mark_node)
730 {
d3769410 731 inform (exp_loc, " in thrown expression");
41990f96
MM
732 return error_mark_node;
733 }
6f30f1f1 734 }
41990f96 735 else
10d3a72a 736 {
e88218fd 737 tree tmp = decay_conversion (exp, tf_warning_or_error);
10d3a72a
PC
738 if (tmp == error_mark_node)
739 return error_mark_node;
740 exp = build2 (INIT_EXPR, temp_type, object, tmp);
741 }
f4a23343 742
b33a0480
JM
743 /* Mark any cleanups from the initialization as MUST_NOT_THROW, since
744 they are run after the exception object is initialized. */
745 cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0);
6de9cd9a 746
6f30f1f1 747 /* Prepend the allocation. */
f293ce4b 748 exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
b33a0480
JM
749
750 /* Force all the cleanups to be evaluated here so that we don't have
751 to do them during unwinding. */
752 exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
72b7eeff 753
52a11cbf 754 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
f4a23343 755
eca7fc57
JM
756 cleanup = NULL_TREE;
757 if (type_build_dtor_call (TREE_TYPE (object)))
52a11cbf 758 {
4b4b2e58 759 tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
098cf31a
PP
760 complete_dtor_identifier, 0,
761 tf_warning_or_error);
4b4b2e58
NS
762 dtor_fn = BASELINK_FUNCTIONS (dtor_fn);
763 mark_used (dtor_fn);
eca7fc57
JM
764 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
765 {
4b4b2e58 766 cxx_mark_addressable (dtor_fn);
eca7fc57 767 /* Pretend it's a normal function. */
4b4b2e58 768 cleanup = build1 (ADDR_EXPR, cleanup_type, dtor_fn);
eca7fc57 769 }
f30432d7 770 }
eca7fc57 771 if (cleanup == NULL_TREE)
7d60be94 772 cleanup = build_int_cst (cleanup_type, 0);
c8094d83 773
52a11cbf 774 /* ??? Indicate that this function call throws throw_type. */
e88218fd
NS
775 tree tmp = cp_build_function_call_nary (throw_fn, tf_warning_or_error,
776 ptr, throw_type, cleanup,
777 NULL_TREE);
72b7eeff 778
6f30f1f1 779 /* Tack on the initialization stuff. */
f293ce4b 780 exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
8d2733ca
MS
781 }
782 else
a3b49ccd 783 {
52a11cbf 784 /* Rethrow current exception. */
4b4b2e58 785 if (!rethrow_fn)
52a11cbf 786 {
e88218fd
NS
787 rethrow_fn = declare_library_fn_1 ("__cxa_rethrow",
788 ECF_NORETURN | ECF_COLD,
789 void_type_node, 0, NULL);
784417d1 790 if (flag_tm && rethrow_fn != error_mark_node)
4b4b2e58
NS
791 apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure"));
792 }
0a35513e 793
6f30f1f1 794 /* ??? Indicate that this function call allows exceptions of the type
c8094d83 795 of the enclosing catch block (if known). */
4b4b2e58 796 exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error);
a3b49ccd 797 }
8d2733ca 798
d3769410 799 exp = build1_loc (loc, THROW_EXPR, void_type_node, exp);
02020185 800
52a11cbf 801 return exp;
8d08fdba 802}
4cfbc546
NS
803
804/* Make sure TYPE is complete, pointer to complete, reference to
805 complete, or pointer to cv void. Issue diagnostic on failure.
838dfd8a 806 Return the zero on failure and nonzero on success. FROM can be
4cfbc546
NS
807 the expr or decl from whence TYPE came, if available. */
808
809static int
5cc3d3b8 810complete_ptr_ref_or_void_ptr_p (tree type, tree from)
4cfbc546
NS
811{
812 int is_ptr;
c8094d83 813
4cfbc546
NS
814 /* Check complete. */
815 type = complete_type_or_else (type, from);
816 if (!type)
817 return 0;
c8094d83 818
4cfbc546 819 /* Or a pointer or ref to one, or cv void *. */
50e10fa8 820 is_ptr = TYPE_PTR_P (type);
9f613f06 821 if (is_ptr || TYPE_REF_P (type))
4cfbc546
NS
822 {
823 tree core = TREE_TYPE (type);
c8094d83 824
b72801e2 825 if (is_ptr && VOID_TYPE_P (core))
0cbd7506 826 /* OK */;
4cfbc546 827 else if (!complete_type_or_else (core, from))
0cbd7506 828 return 0;
4cfbc546
NS
829 }
830 return 1;
831}
832
f9eead1f
PC
833/* If IS_THROW is true return truth-value if T is an expression admissible
834 in throw-expression, i.e. if it is not of incomplete type or a pointer/
835 reference to such a type or of an abstract class type.
836 If IS_THROW is false, likewise for a catch parameter, same requirements
837 for its type plus rvalue reference type is also not admissible. */
d064d75a
GDR
838
839static bool
f9eead1f 840is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw)
d064d75a 841{
f9eead1f
PC
842 tree expr = is_throw ? t : NULL_TREE;
843 tree type = TREE_TYPE (t);
844
845 /* C++11 [except.handle] The exception-declaration shall not denote
846 an incomplete type, an abstract class type, or an rvalue reference
847 type. */
d064d75a
GDR
848
849 /* 15.1/4 [...] The type of the throw-expression shall not be an
0cbd7506
MS
850 incomplete type, or a pointer or a reference to an incomplete
851 type, other than void*, const void*, volatile void*, or
852 const volatile void*. Except for these restriction and the
853 restrictions on type matching mentioned in 15.3, the operand
854 of throw is treated exactly as a function argument in a call
855 (5.2.2) or the operand of a return statement. */
d064d75a
GDR
856 if (!complete_ptr_ref_or_void_ptr_p (type, expr))
857 return false;
858
02a32ab4
RS
859 tree nonref_type = non_reference (type);
860 if (!verify_type_context (input_location, TCTX_EXCEPTIONS, nonref_type))
861 return false;
862
d064d75a 863 /* 10.4/3 An abstract class shall not be used as a parameter type,
0cbd7506
MS
864 as a function return type or as type of an explicit
865 conversion. */
2df663cc
JM
866 else if (abstract_virtuals_error (is_throw ? ACU_THROW : ACU_CATCH, type))
867 return false;
f9eead1f 868 else if (!is_throw
9f613f06 869 && TYPE_REF_P (type)
f9eead1f
PC
870 && TYPE_REF_IS_RVALUE (type))
871 {
a9c697b8 872 error ("cannot declare %<catch%> parameter to be of rvalue "
f9eead1f 873 "reference type %qT", type);
d064d75a
GDR
874 return false;
875 }
785b887e
JM
876 else if (variably_modified_type_p (type, NULL_TREE))
877 {
878 if (is_throw)
d3769410
PC
879 error_at (cp_expr_loc_or_input_loc (expr),
880 "cannot throw expression of type %qT because it involves "
881 "types of variable size", type);
785b887e
JM
882 else
883 error ("cannot catch type %qT because it involves types of "
884 "variable size", type);
885 return false;
886 }
d064d75a
GDR
887
888 return true;
889}
890
1660cb3a
JM
891/* Returns nonzero if FN is a declaration of a standard C library
892 function which is known not to throw.
893
894 [lib.res.on.exception.handling]: None of the functions from the
895 Standard C library shall report an error by throwing an
896 exception, unless it calls a program-supplied function that
897 throws an exception. */
898
899#include "cfns.h"
900
901int
58f9752a 902nothrow_libfn_p (const_tree fn)
1660cb3a
JM
903{
904 tree id;
905
906 if (TREE_PUBLIC (fn)
907 && DECL_EXTERNAL (fn)
92643fea 908 && DECL_NAMESPACE_SCOPE_P (fn)
eb68cb58 909 && DECL_EXTERN_C_P (fn))
1660cb3a
JM
910 /* OK */;
911 else
912 /* Can't be a C library function. */
913 return 0;
914
84b8b0e0
ZW
915 /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
916 unless the system headers are playing rename tricks, and if
917 they are, we don't want to be confused by them. */
918 id = DECL_NAME (fn);
6b56d5f5
JJ
919 const struct libc_name_struct *s
920 = libc_name::libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
921 if (s == NULL)
922 return 0;
923 switch (s->c_ver)
924 {
925 case 89: return 1;
926 case 99: return !flag_iso || flag_isoc99;
927 case 11: return !flag_iso || flag_isoc11;
928 default: gcc_unreachable ();
929 }
1660cb3a 930}
2bc9f1d1
JM
931
932/* Returns nonzero if an exception of type FROM will be caught by a
933 handler for type TO, as per [except.handle]. */
934
43d3b7bc 935static bool
5cc3d3b8 936can_convert_eh (tree to, tree from)
2bc9f1d1 937{
ee76b931
MM
938 to = non_reference (to);
939 from = non_reference (from);
2bc9f1d1 940
43d3b7bc
MP
941 if (same_type_ignoring_top_level_qualifiers_p (to, from))
942 return true;
943
50e10fa8 944 if (TYPE_PTR_P (to) && TYPE_PTR_P (from))
2bc9f1d1
JM
945 {
946 to = TREE_TYPE (to);
947 from = TREE_TYPE (from);
948
949 if (! at_least_as_qualified_p (to, from))
43d3b7bc 950 return false;
2bc9f1d1 951
50e10fa8 952 if (VOID_TYPE_P (to))
43d3b7bc 953 return true;
2bc9f1d1 954
f4f206f4 955 /* Else fall through. */
2bc9f1d1
JM
956 }
957
2d46ec83 958 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
22854930 959 && publicly_uniquely_derived_p (to, from))
43d3b7bc 960 return true;
2bc9f1d1 961
43d3b7bc 962 return false;
2bc9f1d1
JM
963}
964
325c3691
RH
965/* Check whether any of the handlers in I are shadowed by another handler
966 accepting TYPE. Note that the shadowing may not be complete; even if
967 an exception of type B would be caught by a handler for A, there could
968 be a derived class C for which A is an ambiguous base but B is not, so
969 the handler for B would catch an exception of type C. */
2bc9f1d1
JM
970
971static void
325c3691 972check_handlers_1 (tree master, tree_stmt_iterator i)
2bc9f1d1
JM
973{
974 tree type = TREE_TYPE (master);
2bc9f1d1 975
325c3691
RH
976 for (; !tsi_end_p (i); tsi_next (&i))
977 {
978 tree handler = tsi_stmt (i);
979 if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
980 {
44e1f63e 981 auto_diagnostic_group d;
1d87302a
MP
982 if (warning_at (EXPR_LOCATION (handler), OPT_Wexceptions,
983 "exception of type %qT will be caught by earlier "
984 "handler", TREE_TYPE (handler)))
985 inform (EXPR_LOCATION (master), "for type %qT", type);
325c3691 986 break;
0cbd7506 987 }
325c3691 988 }
2bc9f1d1
JM
989}
990
325c3691 991/* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK. */
2bc9f1d1
JM
992
993void
5cc3d3b8 994check_handlers (tree handlers)
2bc9f1d1 995{
325c3691
RH
996 tree_stmt_iterator i;
997
998 /* If we don't have a STATEMENT_LIST, then we've just got one
999 handler, and thus nothing to warn about. */
1000 if (TREE_CODE (handlers) != STATEMENT_LIST)
1001 return;
1002
1003 i = tsi_start (handlers);
1004 if (!tsi_end_p (i))
1005 while (1)
1006 {
0cbd7506 1007 tree handler = tsi_stmt (i);
325c3691
RH
1008 tsi_next (&i);
1009
1010 /* No more handlers; nothing to shadow. */
1011 if (tsi_end_p (i))
1012 break;
1013 if (TREE_TYPE (handler) == NULL_TREE)
69bc6bff
MLI
1014 permerror (EXPR_LOCATION (handler), "%<...%>"
1015 " handler must be the last handler for its try block");
325c3691
RH
1016 else
1017 check_handlers_1 (handler, i);
1018 }
2bc9f1d1 1019}
0a766368
JM
1020
1021/* walk_tree helper for finish_noexcept_expr. Returns non-null if the
1022 expression *TP causes the noexcept operator to evaluate to false.
1023
1024 5.3.7 [expr.noexcept]: The result of the noexcept operator is false if
1025 in a potentially-evaluated context the expression would contain
1026 * a potentially evaluated call to a function, member function,
1027 function pointer, or member function pointer that does not have a
1028 non-throwing exception-specification (15.4),
1029 * a potentially evaluated throw-expression (15.1),
1030 * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1031 where T is a reference type, that requires a run-time check (5.2.7), or
1032 * a potentially evaluated typeid expression (5.2.8) applied to a glvalue
1033 expression whose type is a polymorphic class type (10.3). */
1034
1035static tree
dee00bf6 1036check_noexcept_r (tree *tp, int *walk_subtrees, void *)
0a766368
JM
1037{
1038 tree t = *tp;
1039 enum tree_code code = TREE_CODE (t);
dee00bf6
MP
1040
1041 if (unevaluated_p (code))
1042 *walk_subtrees = false;
1043 else if ((code == CALL_EXPR && CALL_EXPR_FN (t))
1044 || code == AGGR_INIT_EXPR)
0a766368
JM
1045 {
1046 /* We can only use the exception specification of the called function
1047 for determining the value of a noexcept expression; we can't use
1048 TREE_NOTHROW, as it might have a different value in another
1049 translation unit, creating ODR problems.
1050
1051 We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */
babaa9df 1052 tree fn = cp_get_callee (t);
edabbec3
JM
1053 if (concept_check_p (fn))
1054 return NULL_TREE;
5c563482 1055 tree type = TREE_TYPE (fn);
71a93b08 1056 gcc_assert (INDIRECT_TYPE_P (type));
5c563482 1057 type = TREE_TYPE (type);
59f9c2ed
JM
1058
1059 STRIP_NOPS (fn);
0a766368 1060 if (TREE_CODE (fn) == ADDR_EXPR)
fa2200cb
JM
1061 fn = TREE_OPERAND (fn, 0);
1062 if (TREE_CODE (fn) == FUNCTION_DECL)
0a766368
JM
1063 {
1064 /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
1065 and for C library functions known not to throw. */
fa2200cb 1066 if (DECL_EXTERN_C_P (fn)
59f9c2ed
JM
1067 && (DECL_ARTIFICIAL (fn)
1068 || nothrow_libfn_p (fn)))
1069 return TREE_NOTHROW (fn) ? NULL_TREE : fn;
c46f1a17
MP
1070 /* We used to treat a call to a constexpr function as noexcept if
1071 the call was a constant expression (CWG 1129). This has changed
1072 in P0003 whereby noexcept has no special rule for constant
1073 expressions anymore. Since the current behavior is important for
1074 certain library functionality, we treat this as a DR, therefore
1075 adjusting the behavior for C++11 and C++14. Previously, we had
1076 to evaluate the noexcept-specifier's operand here, but that could
1077 cause instantiations that would fail. */
0a766368 1078 }
59f9c2ed
JM
1079 if (!TYPE_NOTHROW_P (type))
1080 return fn;
0a766368
JM
1081 }
1082
1083 return NULL_TREE;
1084}
1085
2c5df20f
JM
1086/* If a function that causes a noexcept-expression to be false isn't
1087 defined yet, remember it and check it for TREE_NOTHROW again at EOF. */
1088
a79683d5 1089struct GTY(()) pending_noexcept {
2c5df20f
JM
1090 tree fn;
1091 location_t loc;
a79683d5 1092};
9771b263 1093static GTY(()) vec<pending_noexcept, va_gc> *pending_noexcept_checks;
2c5df20f
JM
1094
1095/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false. Warn if
1f6c1c82
PP
1096 it can't throw.
1097
1098 TODO: Consider extending -Wnoexcept to do something like walk_subtrees in the
1099 case of a defaulted function that obtained a noexcept(false) spec. */
2c5df20f
JM
1100
1101static void
1102maybe_noexcept_warning (tree fn)
1103{
5035cd66
JM
1104 if (TREE_NOTHROW (fn)
1105 && (!DECL_IN_SYSTEM_HEADER (fn)
1106 || global_dc->dc_warn_system_headers))
2c5df20f 1107 {
3cf63c94 1108 auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
5035cd66
JM
1109 auto_diagnostic_group d;
1110 if (warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
1111 "because of a call to %qD", fn))
1112 inform (DECL_SOURCE_LOCATION (fn),
1113 "but %qD does not throw; perhaps "
1114 "it should be declared %<noexcept%>", fn);
2c5df20f
JM
1115 }
1116}
1117
1118/* Check any functions that weren't defined earlier when they caused a
1119 noexcept expression to evaluate to false. */
1120
1121void
1122perform_deferred_noexcept_checks (void)
1123{
1124 int i;
1125 pending_noexcept *p;
1126 location_t saved_loc = input_location;
9771b263 1127 FOR_EACH_VEC_SAFE_ELT (pending_noexcept_checks, i, p)
2c5df20f
JM
1128 {
1129 input_location = p->loc;
1130 maybe_noexcept_warning (p->fn);
1131 }
1132 input_location = saved_loc;
1133}
1134
0a766368
JM
1135/* Evaluate noexcept ( EXPR ). */
1136
1137tree
59f9c2ed 1138finish_noexcept_expr (tree expr, tsubst_flags_t complain)
0a766368 1139{
d0bb79ac
JM
1140 if (expr == error_mark_node)
1141 return error_mark_node;
1142
0a766368
JM
1143 if (processing_template_decl)
1144 return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
1145
6eaade31
JM
1146 return (expr_noexcept_p (expr, complain)
1147 ? boolean_true_node : boolean_false_node);
1148}
1149
1150/* Returns whether EXPR is noexcept, possibly warning if allowed by
1151 COMPLAIN. */
1152
1153bool
1154expr_noexcept_p (tree expr, tsubst_flags_t complain)
1155{
1156 tree fn;
1157
1158 if (expr == error_mark_node)
1159 return false;
1160
59f9c2ed
JM
1161 fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
1162 if (fn)
1163 {
2c5df20f
JM
1164 if ((complain & tf_warning) && warn_noexcept
1165 && TREE_CODE (fn) == FUNCTION_DECL)
59f9c2ed 1166 {
2c5df20f
JM
1167 if (!DECL_INITIAL (fn))
1168 {
1169 /* Not defined yet; check again at EOF. */
f32682ca 1170 pending_noexcept p = {fn, input_location};
9771b263 1171 vec_safe_push (pending_noexcept_checks, p);
2c5df20f
JM
1172 }
1173 else
1174 maybe_noexcept_warning (fn);
59f9c2ed 1175 }
6eaade31 1176 return false;
59f9c2ed 1177 }
0a766368 1178 else
6eaade31 1179 return true;
0a766368 1180}
3a55fb4c
JM
1181
1182/* Return true iff SPEC is throw() or noexcept(true). */
1183
1184bool
1185nothrow_spec_p (const_tree spec)
1186{
10261728 1187 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
96176bb3
NS
1188
1189 if (spec == empty_except_spec
3a55fb4c
JM
1190 || spec == noexcept_true_spec)
1191 return true;
96176bb3
NS
1192
1193 gcc_assert (!spec
1194 || TREE_VALUE (spec)
1195 || spec == noexcept_false_spec
1196 || TREE_PURPOSE (spec) == error_mark_node
78f7607d 1197 || UNPARSED_NOEXCEPT_SPEC_P (spec)
96176bb3
NS
1198 || processing_template_decl);
1199
3a55fb4c
JM
1200 return false;
1201}
1202
1203/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the
1204 case for things declared noexcept(true) and, with -fnothrow-opt, for
1205 throw() functions. */
1206
1207bool
1208type_noexcept_p (const_tree type)
1209{
1210 tree spec = TYPE_RAISES_EXCEPTIONS (type);
10261728 1211 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
3a55fb4c
JM
1212 if (flag_nothrow_opt)
1213 return nothrow_spec_p (spec);
1214 else
1215 return spec == noexcept_true_spec;
1216}
1217
1218/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type,
1219 i.e. no exception-specification or noexcept(false). */
1220
1221bool
1222type_throw_all_p (const_tree type)
1223{
1224 tree spec = TYPE_RAISES_EXCEPTIONS (type);
10261728 1225 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
3a55fb4c
JM
1226 return spec == NULL_TREE || spec == noexcept_false_spec;
1227}
1228
1229/* Create a representation of the noexcept-specification with
1230 constant-expression of EXPR. COMPLAIN is as for tsubst. */
1231
1232tree
779d8a5a 1233build_noexcept_spec (tree expr, tsubst_flags_t complain)
3a55fb4c 1234{
2cd5333d
MP
1235 if (check_for_bare_parameter_packs (expr))
1236 return error_mark_node;
38f3a877 1237 if (TREE_CODE (expr) != DEFERRED_NOEXCEPT
0d699def 1238 && !value_dependent_expression_p (expr))
fa2200cb 1239 {
cc3bae3d 1240 expr = build_converted_constant_bool_expr (expr, complain);
d417b4f5 1241 expr = instantiate_non_dependent_expr_sfinae (expr, complain);
0309d288 1242 expr = cxx_constant_value (expr);
fa2200cb 1243 }
84fd832c
JJ
1244 if (TREE_CODE (expr) == INTEGER_CST)
1245 {
1246 if (operand_equal_p (expr, boolean_true_node, 0))
1247 return noexcept_true_spec;
1248 else
1249 {
1250 gcc_checking_assert (operand_equal_p (expr, boolean_false_node, 0));
1251 return noexcept_false_spec;
1252 }
1253 }
d0bb79ac
JM
1254 else if (expr == error_mark_node)
1255 return error_mark_node;
3a55fb4c
JM
1256 else
1257 {
84fd832c 1258 gcc_assert (processing_template_decl
10261728 1259 || TREE_CODE (expr) == DEFERRED_NOEXCEPT);
dd39c7d1
JM
1260 if (TREE_CODE (expr) != DEFERRED_NOEXCEPT)
1261 /* Avoid problems with a function type built with a dependent typedef
1262 being reused in another scope (c++/84045). */
1263 expr = strip_typedefs_expr (expr);
3a55fb4c
JM
1264 return build_tree_list (expr, NULL_TREE);
1265 }
1266}
b6c917ff 1267
bcfc2227
JM
1268/* If the current function has a cleanup that might throw, and the return value
1269 has a non-trivial destructor, return a MODIFY_EXPR to set
1270 current_retval_sentinel so that we know that the return value needs to be
1271 destroyed on throw. Otherwise, returns NULL_TREE. */
1272
1273tree
1274maybe_set_retval_sentinel ()
1275{
1276 if (processing_template_decl)
1277 return NULL_TREE;
1278 tree retval = DECL_RESULT (current_function_decl);
1279 if (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (retval)))
1280 return NULL_TREE;
1281 if (!cp_function_chain->throwing_cleanup)
1282 return NULL_TREE;
1283
1284 if (!current_retval_sentinel)
1285 {
1286 /* Just create the temporary now, maybe_splice_retval_cleanup
1287 will do the rest. */
1288 current_retval_sentinel = create_temporary_var (boolean_type_node);
1289 DECL_INITIAL (current_retval_sentinel) = boolean_false_node;
1290 pushdecl_outermost_localscope (current_retval_sentinel);
1291 }
1292
1293 return build2 (MODIFY_EXPR, boolean_type_node,
1294 current_retval_sentinel, boolean_true_node);
1295}
1296
1297/* COMPOUND_STMT is the STATEMENT_LIST for the current function body. If
1298 current_retval_sentinel was set in this function, wrap the body in a
1299 CLEANUP_STMT to destroy the return value on throw. */
1300
1301void
1302maybe_splice_retval_cleanup (tree compound_stmt)
1303{
1304 /* If need_retval_cleanup set current_retval_sentinel, wrap the function body
1305 in a CLEANUP_STMT to handle destroying the return value. */
1306 if (!DECL_CONSTRUCTOR_P (current_function_decl)
1307 && !DECL_DESTRUCTOR_P (current_function_decl)
1308 && current_retval_sentinel)
1309 {
1310 location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
1311
1312 /* Add a DECL_EXPR for current_retval_sentinel. */
1313 tree_stmt_iterator iter = tsi_start (compound_stmt);
1314 tree retval = DECL_RESULT (current_function_decl);
1315 tree decl_expr = build_stmt (loc, DECL_EXPR, current_retval_sentinel);
1316 tsi_link_before (&iter, decl_expr, TSI_SAME_STMT);
1317
1318 /* Skip past other decls, they can't contain a return. */
1319 while (TREE_CODE (tsi_stmt (iter)) == DECL_EXPR)
1320 tsi_next (&iter);
1321 gcc_assert (!tsi_end_p (iter));
1322
1323 /* Wrap the rest of the STATEMENT_LIST in a CLEANUP_STMT. */
1324 tree stmts = NULL_TREE;
1325 while (!tsi_end_p (iter))
1326 {
1327 append_to_statement_list_force (tsi_stmt (iter), &stmts);
1328 tsi_delink (&iter);
1329 }
1330 tree dtor = build_cleanup (retval);
1331 tree cond = build3 (COND_EXPR, void_type_node, current_retval_sentinel,
1332 dtor, void_node);
1333 tree cleanup = build_stmt (loc, CLEANUP_STMT,
1334 stmts, cond, retval);
1335 CLEANUP_EH_ONLY (cleanup) = true;
1336 append_to_statement_list_force (cleanup, &compound_stmt);
1337 }
1338}
1339
b6c917ff 1340#include "gt-cp-except.h"