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