OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [cp/] [except.c] - Blame information for rev 710

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 710 jeremybenn
/* 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
382
build_must_not_throw_expr (tree body, tree cond)
383
{
384
  tree type = body ? TREE_TYPE (body) : void_type_node;
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
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
 
430
  init = convert_from_reference (exp);
431
 
432
  /* If the constructor for the catch parm exits via an exception, we
433
     must call terminate.  See eh23.C.  */
434
  if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
435
    {
436
      /* Generate the copy constructor call directly so we can wrap it.
437
         See also expand_default_init.  */
438
      init = ocp_convert (TREE_TYPE (decl), init,
439
                          CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
440
      /* Force cleanups now to avoid nesting problems with the
441
         MUST_NOT_THROW_EXPR.  */
442
      init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
443
      init = build_must_not_throw_expr (init, NULL_TREE);
444
    }
445
 
446
  decl = pushdecl (decl);
447
 
448
  start_decl_1 (decl, true);
449
  cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
450
                  LOOKUP_ONLYCONVERTING|DIRECT_BIND);
451
}
452
 
453
 
454
/* Routine to see if exception handling is turned on.
455
   DO_WARN is nonzero if we want to inform the user that exception
456
   handling is turned off.
457
 
458
   This is used to ensure that -fexceptions has been specified if the
459
   compiler tries to use any exception-specific functions.  */
460
 
461
static inline int
462
doing_eh (void)
463
{
464
  if (! flag_exceptions)
465
    {
466
      static int warned = 0;
467
      if (! warned)
468
        {
469
          error ("exception handling disabled, use -fexceptions to enable");
470
          warned = 1;
471
        }
472
      return 0;
473
    }
474
  return 1;
475
}
476
 
477
/* Call this to start a catch block.  DECL is the catch parameter.  */
478
 
479
tree
480
expand_start_catch_block (tree decl)
481
{
482
  tree exp;
483
  tree type, init;
484
 
485
  if (! doing_eh ())
486
    return NULL_TREE;
487
 
488
  /* Make sure this declaration is reasonable.  */
489
  if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
490
    decl = error_mark_node;
491
 
492
  if (decl)
493
    type = prepare_eh_type (TREE_TYPE (decl));
494
  else
495
    type = NULL_TREE;
496
 
497
  if (decl && decl_is_java_type (type, 1))
498
    {
499
      /* Java only passes object via pointer and doesn't require
500
         adjusting.  The java object is immediately before the
501
         generic exception header.  */
502
      exp = build_exc_ptr ();
503
      exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
504
      exp = fold_build_pointer_plus (exp,
505
                    fold_build1_loc (input_location,
506
                                     NEGATE_EXPR, sizetype,
507
                                     TYPE_SIZE_UNIT (TREE_TYPE (exp))));
508
      exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
509
      initialize_handler_parm (decl, exp);
510
      return type;
511
    }
512
 
513
  /* Call __cxa_end_catch at the end of processing the exception.  */
514
  push_eh_cleanup (type);
515
 
516
  init = do_begin_catch ();
517
 
518
  /* If there's no decl at all, then all we need to do is make sure
519
     to tell the runtime that we've begun handling the exception.  */
520
  if (decl == NULL || decl == error_mark_node || init == error_mark_node)
521
    finish_expr_stmt (init);
522
 
523
  /* If the C++ object needs constructing, we need to do that before
524
     calling __cxa_begin_catch, so that std::uncaught_exception gets
525
     the right value during the copy constructor.  */
526
  else if (flag_use_cxa_get_exception_ptr
527
           && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
528
    {
529
      exp = do_get_exception_ptr ();
530
      initialize_handler_parm (decl, exp);
531
      finish_expr_stmt (init);
532
    }
533
 
534
  /* Otherwise the type uses a bitwise copy, and we don't have to worry
535
     about the value of std::uncaught_exception and therefore can do the
536
     copy with the return value of __cxa_end_catch instead.  */
537
  else
538
    {
539
      tree init_type = type;
540
 
541
      /* Pointers are passed by values, everything else by reference.  */
542
      if (!TYPE_PTR_P (type))
543
        init_type = build_pointer_type (type);
544
      if (init_type != TREE_TYPE (init))
545
        init = build1 (NOP_EXPR, init_type, init);
546
      exp = create_temporary_var (init_type);
547
      DECL_REGISTER (exp) = 1;
548
      cp_finish_decl (exp, init, /*init_const_expr=*/false,
549
                      NULL_TREE, LOOKUP_ONLYCONVERTING);
550
      initialize_handler_parm (decl, exp);
551
    }
552
 
553
  return type;
554
}
555
 
556
 
557
/* Call this to end a catch block.  Its responsible for emitting the
558
   code to handle jumping back to the correct place, and for emitting
559
   the label to jump to if this catch block didn't match.  */
560
 
561
void
562
expand_end_catch_block (void)
563
{
564
  if (! doing_eh ())
565
    return;
566
 
567
  /* The exception being handled is rethrown if control reaches the end of
568
     a handler of the function-try-block of a constructor or destructor.  */
569
  if (in_function_try_handler
570
      && (DECL_CONSTRUCTOR_P (current_function_decl)
571
          || DECL_DESTRUCTOR_P (current_function_decl)))
572
    finish_expr_stmt (build_throw (NULL_TREE));
573
}
574
 
575
tree
576
begin_eh_spec_block (void)
577
{
578
  tree r;
579
  location_t spec_location = DECL_SOURCE_LOCATION (current_function_decl);
580
 
581
  /* A noexcept specification (or throw() with -fnothrow-opt) is a
582
     MUST_NOT_THROW_EXPR.  */
583
  if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl)))
584
    {
585
      r = build_stmt (spec_location, MUST_NOT_THROW_EXPR,
586
                      NULL_TREE, NULL_TREE);
587
      TREE_SIDE_EFFECTS (r) = 1;
588
    }
589
  else
590
    r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
591
  add_stmt (r);
592
  TREE_OPERAND (r, 0) = push_stmt_list ();
593
  return r;
594
}
595
 
596
void
597
finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
598
{
599
  tree raises;
600
 
601
  TREE_OPERAND (eh_spec_block, 0)
602
    = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0));
603
 
604
  if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR)
605
    return;
606
 
607
  /* Strip cv quals, etc, from the specification types.  */
608
  for (raises = NULL_TREE;
609
       raw_raises && TREE_VALUE (raw_raises);
610
       raw_raises = TREE_CHAIN (raw_raises))
611
    {
612
      tree type = prepare_eh_type (TREE_VALUE (raw_raises));
613
      tree tinfo = eh_type_info (type);
614
 
615
      mark_used (tinfo);
616
      raises = tree_cons (NULL_TREE, type, raises);
617
    }
618
 
619
  EH_SPEC_RAISES (eh_spec_block) = raises;
620
}
621
 
622
/* Return a pointer to a buffer for an exception object of type TYPE.  */
623
 
624
static tree
625
do_allocate_exception (tree type)
626
{
627
  tree fn;
628
 
629
  fn = get_identifier ("__cxa_allocate_exception");
630
  if (!get_global_value_if_present (fn, &fn))
631
    {
632
      /* Declare void *__cxa_allocate_exception(size_t) throw().  */
633
      fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
634
 
635
      if (flag_tm)
636
        {
637
          tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
638
          if (!get_global_value_if_present (fn2, &fn2))
639
            fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
640
                                              size_type_node);
641
          apply_tm_attr (fn2, get_identifier ("transaction_pure"));
642
          record_tm_replacement (fn, fn2);
643
        }
644
    }
645
 
646
  return cp_build_function_call_nary (fn, tf_warning_or_error,
647
                                      size_in_bytes (type), NULL_TREE);
648
}
649
 
650
/* Call __cxa_free_exception from a cleanup.  This is never invoked
651
   directly, but see the comment for stabilize_throw_expr.  */
652
 
653
static tree
654
do_free_exception (tree ptr)
655
{
656
  tree fn;
657
 
658
  fn = get_identifier ("__cxa_free_exception");
659
  if (!get_global_value_if_present (fn, &fn))
660
    {
661
      /* Declare void __cxa_free_exception (void *) throw().  */
662
      fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
663
    }
664
 
665
  return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
666
}
667
 
668
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
669
   Called from build_throw via walk_tree_without_duplicates.  */
670
 
671
static tree
672
wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
673
                 void *data ATTRIBUTE_UNUSED)
674
{
675
  tree exp = *tp;
676
  tree cleanup;
677
 
678
  /* Don't walk into types.  */
679
  if (TYPE_P (exp))
680
    {
681
      *walk_subtrees = 0;
682
      return NULL_TREE;
683
    }
684
  if (TREE_CODE (exp) != TARGET_EXPR)
685
    return NULL_TREE;
686
 
687
  cleanup = TARGET_EXPR_CLEANUP (exp);
688
  if (cleanup)
689
    {
690
      cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup,
691
                        NULL_TREE);
692
      TARGET_EXPR_CLEANUP (exp) = cleanup;
693
    }
694
 
695
  /* Keep iterating.  */
696
  return NULL_TREE;
697
}
698
 
699
/* Build a throw expression.  */
700
 
701
tree
702
build_throw (tree exp)
703
{
704
  tree fn;
705
 
706
  if (exp == error_mark_node)
707
    return exp;
708
 
709
  if (processing_template_decl)
710
    {
711
      if (cfun)
712
        current_function_returns_abnormally = 1;
713
      exp = build_min (THROW_EXPR, void_type_node, exp);
714
      SET_EXPR_LOCATION (exp, input_location);
715
      return exp;
716
    }
717
 
718
  if (exp == null_node)
719
    warning (0, "throwing NULL, which has integral, not pointer type");
720
 
721
  if (exp != NULL_TREE)
722
    {
723
      if (!is_admissible_throw_operand (exp))
724
        return error_mark_node;
725
    }
726
 
727
  if (! doing_eh ())
728
    return error_mark_node;
729
 
730
  if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
731
    {
732
      tree fn = get_identifier ("_Jv_Throw");
733
      if (!get_global_value_if_present (fn, &fn))
734
        {
735
          /* Declare void _Jv_Throw (void *).  */
736
          tree tmp;
737
          tmp = build_function_type_list (ptr_type_node,
738
                                          ptr_type_node, NULL_TREE);
739
          fn = push_throw_library_fn (fn, tmp);
740
        }
741
      else if (really_overloaded_fn (fn))
742
        {
743
          error ("%qD should never be overloaded", fn);
744
          return error_mark_node;
745
        }
746
      fn = OVL_CURRENT (fn);
747
      exp = cp_build_function_call_nary (fn, tf_warning_or_error,
748
                                         exp, NULL_TREE);
749
    }
750
  else if (exp)
751
    {
752
      tree throw_type;
753
      tree temp_type;
754
      tree cleanup;
755
      tree object, ptr;
756
      tree tmp;
757
      tree allocate_expr;
758
 
759
      /* The CLEANUP_TYPE is the internal type of a destructor.  */
760
      if (!cleanup_type)
761
        {
762
          tmp = build_function_type_list (void_type_node,
763
                                          ptr_type_node, NULL_TREE);
764
          cleanup_type = build_pointer_type (tmp);
765
        }
766
 
767
      fn = get_identifier ("__cxa_throw");
768
      if (!get_global_value_if_present (fn, &fn))
769
        {
770
          /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
771
          /* ??? Second argument is supposed to be "std::type_info*".  */
772
          tmp = build_function_type_list (void_type_node,
773
                                          ptr_type_node, ptr_type_node,
774
                                          cleanup_type, NULL_TREE);
775
          fn = push_throw_library_fn (fn, tmp);
776
 
777
          if (flag_tm)
778
            {
779
              tree fn2 = get_identifier ("_ITM_cxa_throw");
780
              if (!get_global_value_if_present (fn2, &fn2))
781
                fn2 = push_throw_library_fn (fn2, tmp);
782
              apply_tm_attr (fn2, get_identifier ("transaction_pure"));
783
              record_tm_replacement (fn, fn2);
784
            }
785
        }
786
 
787
      /* [except.throw]
788
 
789
         A throw-expression initializes a temporary object, the type
790
         of which is determined by removing any top-level
791
         cv-qualifiers from the static type of the operand of throw
792
         and adjusting the type from "array of T" or "function return
793
         T" to "pointer to T" or "pointer to function returning T"
794
         respectively.  */
795
      temp_type = is_bitfield_expr_with_lowered_type (exp);
796
      if (!temp_type)
797
        temp_type = cv_unqualified (type_decays_to (TREE_TYPE (exp)));
798
 
799
      /* OK, this is kind of wacky.  The standard says that we call
800
         terminate when the exception handling mechanism, after
801
         completing evaluation of the expression to be thrown but
802
         before the exception is caught (_except.throw_), calls a
803
         user function that exits via an uncaught exception.
804
 
805
         So we have to protect the actual initialization of the
806
         exception object with terminate(), but evaluate the
807
         expression first.  Since there could be temps in the
808
         expression, we need to handle that, too.  We also expand
809
         the call to __cxa_allocate_exception first (which doesn't
810
         matter, since it can't throw).  */
811
 
812
      /* Allocate the space for the exception.  */
813
      allocate_expr = do_allocate_exception (temp_type);
814
      allocate_expr = get_target_expr (allocate_expr);
815
      ptr = TARGET_EXPR_SLOT (allocate_expr);
816
      TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr);
817
      CLEANUP_EH_ONLY (allocate_expr) = 1;
818
 
819
      object = build_nop (build_pointer_type (temp_type), ptr);
820
      object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
821
 
822
      /* And initialize the exception object.  */
823
      if (CLASS_TYPE_P (temp_type))
824
        {
825
          int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
826
          VEC(tree,gc) *exp_vec;
827
 
828
          /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
829
             treated as an rvalue for the purposes of overload resolution
830
             to favor move constructors over copy constructors.  */
831
          if (/* Must be a local, automatic variable.  */
832
              TREE_CODE (exp) == VAR_DECL
833
              && DECL_CONTEXT (exp) == current_function_decl
834
              && ! TREE_STATIC (exp)
835
              /* The variable must not have the `volatile' qualifier.  */
836
              && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
837
            flags = flags | LOOKUP_PREFER_RVALUE;
838
 
839
          /* Call the copy constructor.  */
840
          exp_vec = make_tree_vector_single (exp);
841
          exp = (build_special_member_call
842
                 (object, complete_ctor_identifier, &exp_vec,
843
                  TREE_TYPE (object), flags, tf_warning_or_error));
844
          release_tree_vector (exp_vec);
845
          if (exp == error_mark_node)
846
            {
847
              error ("  in thrown expression");
848
              return error_mark_node;
849
            }
850
        }
851
      else
852
        {
853
          tmp = decay_conversion (exp);
854
          if (tmp == error_mark_node)
855
            return error_mark_node;
856
          exp = build2 (INIT_EXPR, temp_type, object, tmp);
857
        }
858
 
859
      /* Mark any cleanups from the initialization as MUST_NOT_THROW, since
860
         they are run after the exception object is initialized.  */
861
      cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0);
862
 
863
      /* Prepend the allocation.  */
864
      exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
865
 
866
      /* Force all the cleanups to be evaluated here so that we don't have
867
         to do them during unwinding.  */
868
      exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
869
 
870
      throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
871
 
872
      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
873
        {
874
          cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
875
                                     complete_dtor_identifier, 0);
876
          cleanup = BASELINK_FUNCTIONS (cleanup);
877
          mark_used (cleanup);
878
          cxx_mark_addressable (cleanup);
879
          /* Pretend it's a normal function.  */
880
          cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
881
        }
882
      else
883
        cleanup = build_int_cst (cleanup_type, 0);
884
 
885
      /* ??? Indicate that this function call throws throw_type.  */
886
      tmp = cp_build_function_call_nary (fn, tf_warning_or_error,
887
                                         ptr, throw_type, cleanup, NULL_TREE);
888
 
889
      /* Tack on the initialization stuff.  */
890
      exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
891
    }
892
  else
893
    {
894
      /* Rethrow current exception.  */
895
 
896
      tree fn = get_identifier ("__cxa_rethrow");
897
      if (!get_global_value_if_present (fn, &fn))
898
        {
899
          /* Declare void __cxa_rethrow (void).  */
900
          fn = push_throw_library_fn
901
            (fn, build_function_type_list (void_type_node, NULL_TREE));
902
        }
903
 
904
      if (flag_tm)
905
        apply_tm_attr (fn, get_identifier ("transaction_pure"));
906
 
907
      /* ??? Indicate that this function call allows exceptions of the type
908
         of the enclosing catch block (if known).  */
909
      exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
910
    }
911
 
912
  exp = build1 (THROW_EXPR, void_type_node, exp);
913
  SET_EXPR_LOCATION (exp, input_location);
914
 
915
  return exp;
916
}
917
 
918
/* Make sure TYPE is complete, pointer to complete, reference to
919
   complete, or pointer to cv void. Issue diagnostic on failure.
920
   Return the zero on failure and nonzero on success. FROM can be
921
   the expr or decl from whence TYPE came, if available.  */
922
 
923
static int
924
complete_ptr_ref_or_void_ptr_p (tree type, tree from)
925
{
926
  int is_ptr;
927
 
928
  /* Check complete.  */
929
  type = complete_type_or_else (type, from);
930
  if (!type)
931
    return 0;
932
 
933
  /* Or a pointer or ref to one, or cv void *.  */
934
  is_ptr = TREE_CODE (type) == POINTER_TYPE;
935
  if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
936
    {
937
      tree core = TREE_TYPE (type);
938
 
939
      if (is_ptr && VOID_TYPE_P (core))
940
        /* OK */;
941
      else if (!complete_type_or_else (core, from))
942
        return 0;
943
    }
944
  return 1;
945
}
946
 
947
/* Return truth-value if EXPRESSION is admissible in throw-expression,
948
   i.e. if it is not of incomplete type or a pointer/reference to such
949
   a type or of an abstract class type.  */
950
 
951
static bool
952
is_admissible_throw_operand (tree expr)
953
{
954
  tree type = TREE_TYPE (expr);
955
 
956
  /* 15.1/4 [...] The type of the throw-expression shall not be an
957
            incomplete type, or a pointer or a reference to an incomplete
958
            type, other than void*, const void*, volatile void*, or
959
            const volatile void*.  Except for these restriction and the
960
            restrictions on type matching mentioned in 15.3, the operand
961
            of throw is treated exactly as a function argument in a call
962
            (5.2.2) or the operand of a return statement.  */
963
  if (!complete_ptr_ref_or_void_ptr_p (type, expr))
964
    return false;
965
 
966
  /* 10.4/3 An abstract class shall not be used as a parameter type,
967
            as a function return type or as type of an explicit
968
            conversion.  */
969
  else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
970
    {
971
      error ("expression %qE of abstract class type %qT cannot "
972
             "be used in throw-expression", expr, type);
973
      return false;
974
    }
975
 
976
  return true;
977
}
978
 
979
/* Returns nonzero if FN is a declaration of a standard C library
980
   function which is known not to throw.
981
 
982
   [lib.res.on.exception.handling]: None of the functions from the
983
   Standard C library shall report an error by throwing an
984
   exception, unless it calls a program-supplied function that
985
   throws an exception.  */
986
 
987
#include "cfns.h"
988
 
989
int
990
nothrow_libfn_p (const_tree fn)
991
{
992
  tree id;
993
 
994
  if (TREE_PUBLIC (fn)
995
      && DECL_EXTERNAL (fn)
996
      && DECL_NAMESPACE_SCOPE_P (fn)
997
      && DECL_EXTERN_C_P (fn))
998
    /* OK */;
999
  else
1000
    /* Can't be a C library function.  */
1001
    return 0;
1002
 
1003
  /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
1004
     unless the system headers are playing rename tricks, and if
1005
     they are, we don't want to be confused by them.  */
1006
  id = DECL_NAME (fn);
1007
  return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
1008
}
1009
 
1010
/* Returns nonzero if an exception of type FROM will be caught by a
1011
   handler for type TO, as per [except.handle].  */
1012
 
1013
static int
1014
can_convert_eh (tree to, tree from)
1015
{
1016
  to = non_reference (to);
1017
  from = non_reference (from);
1018
 
1019
  if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
1020
    {
1021
      to = TREE_TYPE (to);
1022
      from = TREE_TYPE (from);
1023
 
1024
      if (! at_least_as_qualified_p (to, from))
1025
        return 0;
1026
 
1027
      if (TREE_CODE (to) == VOID_TYPE)
1028
        return 1;
1029
 
1030
      /* Else fall through.  */
1031
    }
1032
 
1033
  if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
1034
      && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
1035
    return 1;
1036
 
1037
  return 0;
1038
}
1039
 
1040
/* Check whether any of the handlers in I are shadowed by another handler
1041
   accepting TYPE.  Note that the shadowing may not be complete; even if
1042
   an exception of type B would be caught by a handler for A, there could
1043
   be a derived class C for which A is an ambiguous base but B is not, so
1044
   the handler for B would catch an exception of type C.  */
1045
 
1046
static void
1047
check_handlers_1 (tree master, tree_stmt_iterator i)
1048
{
1049
  tree type = TREE_TYPE (master);
1050
 
1051
  for (; !tsi_end_p (i); tsi_next (&i))
1052
    {
1053
      tree handler = tsi_stmt (i);
1054
      if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
1055
        {
1056
          warning_at (EXPR_LOCATION (handler), 0,
1057
                      "exception of type %qT will be caught",
1058
                      TREE_TYPE (handler));
1059
          warning_at (EXPR_LOCATION (master), 0,
1060
                      "   by earlier handler for %qT", type);
1061
          break;
1062
        }
1063
    }
1064
}
1065
 
1066
/* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK.  */
1067
 
1068
void
1069
check_handlers (tree handlers)
1070
{
1071
  tree_stmt_iterator i;
1072
 
1073
  /* If we don't have a STATEMENT_LIST, then we've just got one
1074
     handler, and thus nothing to warn about.  */
1075
  if (TREE_CODE (handlers) != STATEMENT_LIST)
1076
    return;
1077
 
1078
  i = tsi_start (handlers);
1079
  if (!tsi_end_p (i))
1080
    while (1)
1081
      {
1082
        tree handler = tsi_stmt (i);
1083
        tsi_next (&i);
1084
 
1085
        /* No more handlers; nothing to shadow.  */
1086
        if (tsi_end_p (i))
1087
          break;
1088
        if (TREE_TYPE (handler) == NULL_TREE)
1089
          permerror (EXPR_LOCATION (handler), "%<...%>"
1090
                     " handler must be the last handler for its try block");
1091
        else
1092
          check_handlers_1 (handler, i);
1093
      }
1094
}
1095
 
1096
/* walk_tree helper for finish_noexcept_expr.  Returns non-null if the
1097
   expression *TP causes the noexcept operator to evaluate to false.
1098
 
1099
   5.3.7 [expr.noexcept]: The result of the noexcept operator is false if
1100
   in a potentially-evaluated context the expression would contain
1101
   * a potentially evaluated call to a function, member function,
1102
     function pointer, or member function pointer that does not have a
1103
     non-throwing exception-specification (15.4),
1104
   * a potentially evaluated throw-expression (15.1),
1105
   * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1106
     where T is a reference type, that requires a run-time check (5.2.7), or
1107
   * a potentially evaluated typeid expression (5.2.8) applied to a glvalue
1108
     expression whose type is a polymorphic class type (10.3).  */
1109
 
1110
static tree
1111
check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
1112
                  void *data ATTRIBUTE_UNUSED)
1113
{
1114
  tree t = *tp;
1115
  enum tree_code code = TREE_CODE (t);
1116
  if (code == CALL_EXPR
1117
      || code == AGGR_INIT_EXPR)
1118
    {
1119
      /* We can only use the exception specification of the called function
1120
         for determining the value of a noexcept expression; we can't use
1121
         TREE_NOTHROW, as it might have a different value in another
1122
         translation unit, creating ODR problems.
1123
 
1124
         We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */
1125
      tree fn = (code == AGGR_INIT_EXPR
1126
                 ? AGGR_INIT_EXPR_FN (t) : CALL_EXPR_FN (t));
1127
      tree type = TREE_TYPE (TREE_TYPE (fn));
1128
 
1129
      STRIP_NOPS (fn);
1130
      if (TREE_CODE (fn) == ADDR_EXPR)
1131
        fn = TREE_OPERAND (fn, 0);
1132
      if (TREE_CODE (fn) == FUNCTION_DECL)
1133
        {
1134
          /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
1135
             and for C library functions known not to throw.  */
1136
          if (DECL_EXTERN_C_P (fn)
1137
              && (DECL_ARTIFICIAL (fn)
1138
                  || nothrow_libfn_p (fn)))
1139
            return TREE_NOTHROW (fn) ? NULL_TREE : fn;
1140
          /* A call to a constexpr function is noexcept if the call
1141
             is a constant expression.  */
1142
          if (DECL_DECLARED_CONSTEXPR_P (fn)
1143
              && is_sub_constant_expr (t))
1144
            return NULL_TREE;
1145
        }
1146
      if (!TYPE_NOTHROW_P (type))
1147
        return fn;
1148
    }
1149
 
1150
  return NULL_TREE;
1151
}
1152
 
1153
/* If a function that causes a noexcept-expression to be false isn't
1154
   defined yet, remember it and check it for TREE_NOTHROW again at EOF.  */
1155
 
1156
typedef struct GTY(()) pending_noexcept {
1157
  tree fn;
1158
  location_t loc;
1159
} pending_noexcept;
1160
DEF_VEC_O(pending_noexcept);
1161
DEF_VEC_ALLOC_O(pending_noexcept,gc);
1162
static GTY(()) VEC(pending_noexcept,gc) *pending_noexcept_checks;
1163
 
1164
/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false.  Warn if
1165
   it can't throw.  */
1166
 
1167
static void
1168
maybe_noexcept_warning (tree fn)
1169
{
1170
  if (TREE_NOTHROW (fn))
1171
    {
1172
      warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
1173
               "because of a call to %qD", fn);
1174
      warning (OPT_Wnoexcept, "but %q+D does not throw; perhaps "
1175
               "it should be declared %<noexcept%>", fn);
1176
    }
1177
}
1178
 
1179
/* Check any functions that weren't defined earlier when they caused a
1180
   noexcept expression to evaluate to false.  */
1181
 
1182
void
1183
perform_deferred_noexcept_checks (void)
1184
{
1185
  int i;
1186
  pending_noexcept *p;
1187
  location_t saved_loc = input_location;
1188
  FOR_EACH_VEC_ELT (pending_noexcept, pending_noexcept_checks, i, p)
1189
    {
1190
      input_location = p->loc;
1191
      maybe_noexcept_warning (p->fn);
1192
    }
1193
  input_location = saved_loc;
1194
}
1195
 
1196
/* Evaluate noexcept ( EXPR ).  */
1197
 
1198
tree
1199
finish_noexcept_expr (tree expr, tsubst_flags_t complain)
1200
{
1201
  if (expr == error_mark_node)
1202
    return error_mark_node;
1203
 
1204
  if (processing_template_decl)
1205
    return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
1206
 
1207
  return (expr_noexcept_p (expr, complain)
1208
          ? boolean_true_node : boolean_false_node);
1209
}
1210
 
1211
/* Returns whether EXPR is noexcept, possibly warning if allowed by
1212
   COMPLAIN.  */
1213
 
1214
bool
1215
expr_noexcept_p (tree expr, tsubst_flags_t complain)
1216
{
1217
  tree fn;
1218
 
1219
  if (expr == error_mark_node)
1220
    return false;
1221
 
1222
  fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
1223
  if (fn)
1224
    {
1225
      if ((complain & tf_warning) && warn_noexcept
1226
          && TREE_CODE (fn) == FUNCTION_DECL)
1227
        {
1228
          if (!DECL_INITIAL (fn))
1229
            {
1230
              /* Not defined yet; check again at EOF.  */
1231
              pending_noexcept *p
1232
                = VEC_safe_push (pending_noexcept, gc,
1233
                                 pending_noexcept_checks, NULL);
1234
              p->fn = fn;
1235
              p->loc = input_location;
1236
            }
1237
          else
1238
            maybe_noexcept_warning (fn);
1239
        }
1240
      return false;
1241
    }
1242
  else
1243
    return true;
1244
}
1245
 
1246
/* Return true iff SPEC is throw() or noexcept(true).  */
1247
 
1248
bool
1249
nothrow_spec_p (const_tree spec)
1250
{
1251
  gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
1252
  if (spec == NULL_TREE
1253
      || TREE_VALUE (spec) != NULL_TREE
1254
      || spec == noexcept_false_spec)
1255
    return false;
1256
  if (TREE_PURPOSE (spec) == NULL_TREE
1257
      || spec == noexcept_true_spec)
1258
    return true;
1259
  gcc_assert (processing_template_decl
1260
              || TREE_PURPOSE (spec) == error_mark_node);
1261
  return false;
1262
}
1263
 
1264
/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept.  This is the
1265
   case for things declared noexcept(true) and, with -fnothrow-opt, for
1266
   throw() functions.  */
1267
 
1268
bool
1269
type_noexcept_p (const_tree type)
1270
{
1271
  tree spec = TYPE_RAISES_EXCEPTIONS (type);
1272
  gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
1273
  if (flag_nothrow_opt)
1274
    return nothrow_spec_p (spec);
1275
  else
1276
    return spec == noexcept_true_spec;
1277
}
1278
 
1279
/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type,
1280
   i.e. no exception-specification or noexcept(false).  */
1281
 
1282
bool
1283
type_throw_all_p (const_tree type)
1284
{
1285
  tree spec = TYPE_RAISES_EXCEPTIONS (type);
1286
  gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
1287
  return spec == NULL_TREE || spec == noexcept_false_spec;
1288
}
1289
 
1290
/* Create a representation of the noexcept-specification with
1291
   constant-expression of EXPR.  COMPLAIN is as for tsubst.  */
1292
 
1293
tree
1294
build_noexcept_spec (tree expr, int complain)
1295
{
1296
  /* This isn't part of the signature, so don't bother trying to evaluate
1297
     it until instantiation.  */
1298
  if (!processing_template_decl && TREE_CODE (expr) != DEFERRED_NOEXCEPT)
1299
    {
1300
      expr = perform_implicit_conversion_flags (boolean_type_node, expr,
1301
                                                complain,
1302
                                                LOOKUP_NORMAL);
1303
      expr = cxx_constant_value (expr);
1304
    }
1305
  if (expr == boolean_true_node)
1306
    return noexcept_true_spec;
1307
  else if (expr == boolean_false_node)
1308
    return noexcept_false_spec;
1309
  else if (expr == error_mark_node)
1310
    return error_mark_node;
1311
  else
1312
    {
1313
      gcc_assert (processing_template_decl || expr == error_mark_node
1314
                  || TREE_CODE (expr) == DEFERRED_NOEXCEPT);
1315
      return build_tree_list (expr, NULL_TREE);
1316
    }
1317
}
1318
 
1319
#include "gt-cp-except.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.