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