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