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