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