]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/except.c
decl2.c (comdat_linkage): Don't externalize explicit instantiations.
[gcc.git] / gcc / cp / except.c
CommitLineData
8d08fdba 1/* Handle exceptional things in C++.
c913b6f1 2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
43c6a96a 3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
8d2733ca
MS
4 Contributed by Michael Tiemann <tiemann@cygnus.com>
5 Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
6 initial re-implementation courtesy Tad Hunt.
8d08fdba 7
f5adbb8d 8This file is part of GCC.
8d08fdba 9
f5adbb8d 10GCC is free software; you can redistribute it and/or modify
8d08fdba
MS
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
f5adbb8d 15GCC is distributed in the hope that it will be useful,
8d08fdba
MS
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
f5adbb8d 21along with GCC; see the file COPYING. If not, write to
e9fa0c7c
RK
22the Free Software Foundation, 59 Temple Place - Suite 330,
23Boston, MA 02111-1307, USA. */
8d08fdba
MS
24
25
8d08fdba 26#include "config.h"
8d052bc7 27#include "system.h"
4977bab6
ZW
28#include "coretypes.h"
29#include "tm.h"
8d08fdba
MS
30#include "tree.h"
31#include "rtl.h"
8f17b5c5 32#include "expr.h"
e78d8e51 33#include "libfuncs.h"
8d08fdba
MS
34#include "cp-tree.h"
35#include "flags.h"
21451173 36#include "output.h"
6467930b 37#include "except.h"
54f92bfb 38#include "toplev.h"
6f30f1f1 39#include "tree-inline.h"
8d08fdba 40
5cc3d3b8
GDR
41static void push_eh_cleanup (tree);
42static tree prepare_eh_type (tree);
43static tree build_eh_type_type (tree);
44static tree do_begin_catch (void);
45static int dtor_nothrow (tree);
46static tree do_end_catch (tree);
47static void push_eh_cleanup (tree);
48static bool decl_is_java_type (tree decl, int err);
49static void initialize_handler_parm (tree, tree);
50static tree do_allocate_exception (tree);
51static tree stabilize_throw_expr (tree, tree *);
52static tree wrap_cleanups_r (tree *, int *, void *);
53static int complete_ptr_ref_or_void_ptr_p (tree, tree);
54static bool is_admissible_throw_operand (tree);
55static int can_convert_eh (tree, tree);
56static void check_handlers_1 (tree, tree);
57static tree cp_protect_cleanup_actions (void);
8d2733ca 58
52a11cbf 59/* Sets up all the global eh stuff that needs to be initialized at the
bbd0d54a 60 start of compilation. */
8d08fdba 61
8d08fdba 62void
5cc3d3b8 63init_exception_processing (void)
8d08fdba 64{
52a11cbf
RH
65 tree tmp;
66
52a11cbf 67 /* void std::terminate (); */
1dbb6023 68 push_namespace (std_identifier);
52a11cbf
RH
69 tmp = build_function_type (void_type_node, void_list_node);
70 terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
9cd64686 71 TREE_THIS_VOLATILE (terminate_node) = 1;
0c11ada6 72 TREE_NOTHROW (terminate_node) = 1;
1dbb6023 73 pop_namespace ();
8ccc31eb 74
52a11cbf
RH
75 /* void __cxa_call_unexpected(void *); */
76 tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
77 tmp = build_function_type (void_type_node, tmp);
78 call_unexpected_node
79 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
6874c264 80
52a11cbf
RH
81 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
82 ? "__gxx_personality_sj0"
83 : "__gxx_personality_v0");
6874c264 84
52a11cbf 85 lang_eh_runtime_type = build_eh_type_type;
e6855a2d 86 lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
6874c264
JM
87}
88
e6855a2d 89/* Returns an expression to be executed if an unhandled exception is
aba649ba 90 propagated out of a cleanup region. */
e6855a2d
MM
91
92static tree
5cc3d3b8 93cp_protect_cleanup_actions (void)
e6855a2d
MM
94{
95 /* [except.terminate]
96
97 When the destruction of an object during stack unwinding exits
98 using an exception ... void terminate(); is called. */
99 return build_call (terminate_node, NULL_TREE);
100}
101
6874c264 102static tree
5cc3d3b8 103prepare_eh_type (tree type)
8d08fdba 104{
52a11cbf
RH
105 if (type == NULL_TREE)
106 return type;
f30432d7
MS
107 if (type == error_mark_node)
108 return error_mark_node;
8d2733ca 109
e92cc029 110 /* peel back references, so they match. */
f30432d7
MS
111 if (TREE_CODE (type) == REFERENCE_TYPE)
112 type = TREE_TYPE (type);
8d08fdba 113
e92cc029 114 /* Peel off cv qualifiers. */
f30432d7 115 type = TYPE_MAIN_VARIANT (type);
8d2733ca 116
52a11cbf 117 return type;
8d08fdba 118}
8d08fdba 119
e5f614d7 120/* Build the address of a typeinfo decl for use in the runtime
c6002625 121 matching field of the exception model. */
5816cb14
AM
122
123static tree
5cc3d3b8 124build_eh_type_type (tree type)
5816cb14 125{
5816cb14 126 tree exp;
5816cb14 127
93ca4ba7
JM
128 if (type == NULL_TREE || type == error_mark_node)
129 return type;
5816cb14 130
52a11cbf
RH
131 if (decl_is_java_type (type, 0))
132 exp = build_java_class_ref (TREE_TYPE (type));
133 else
134 exp = get_tinfo_decl (type);
5816cb14 135
e5f614d7 136 mark_used (exp);
db48b831 137 exp = build1 (ADDR_EXPR, ptr_type_node, exp);
5816cb14 138
52a11cbf 139 return exp;
5816cb14
AM
140}
141
52a11cbf 142tree
5cc3d3b8 143build_exc_ptr (void)
52a11cbf
RH
144{
145 return build (EXC_PTR_EXPR, ptr_type_node);
146}
147
148/* Build up a call to __cxa_begin_catch, to tell the runtime that the
149 exception has been handled. */
93ca4ba7 150
52a11cbf 151static tree
5cc3d3b8 152do_begin_catch (void)
9c606f69 153{
52a11cbf
RH
154 tree fn;
155
156 fn = get_identifier ("__cxa_begin_catch");
157 if (IDENTIFIER_GLOBAL_VALUE (fn))
158 fn = IDENTIFIER_GLOBAL_VALUE (fn);
159 else
9c606f69 160 {
52a11cbf
RH
161 /* Declare void* __cxa_begin_catch (void *). */
162 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
163 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
9c606f69 164 }
52a11cbf
RH
165
166 return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
167 NULL_TREE));
9c606f69
AM
168}
169
93ca4ba7
JM
170/* Returns nonzero if cleaning up an exception of type TYPE (which can be
171 NULL_TREE for a ... handler) will not throw an exception. */
172
173static int
5cc3d3b8 174dtor_nothrow (tree type)
93ca4ba7 175{
93ca4ba7
JM
176 if (type == NULL_TREE)
177 return 0;
178
179 if (! TYPE_HAS_DESTRUCTOR (type))
180 return 1;
181
50ad9642 182 return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
93ca4ba7
JM
183}
184
52a11cbf 185/* Build up a call to __cxa_end_catch, to destroy the exception object
93ca4ba7 186 for the current catch block if no others are currently using it. */
6467930b 187
c7ae64f2 188static tree
5cc3d3b8 189do_end_catch (tree type)
72b7eeff 190{
6874c264 191 tree fn, cleanup;
52a11cbf
RH
192
193 fn = get_identifier ("__cxa_end_catch");
6874c264
JM
194 if (IDENTIFIER_GLOBAL_VALUE (fn))
195 fn = IDENTIFIER_GLOBAL_VALUE (fn);
196 else
197 {
52a11cbf
RH
198 /* Declare void __cxa_end_catch (). */
199 fn = push_void_library_fn (fn, void_list_node);
0c11ada6
JM
200 /* This can throw if the destructor for the exception throws. */
201 TREE_NOTHROW (fn) = 0;
6874c264 202 }
72b7eeff 203
52a11cbf 204 cleanup = build_function_call (fn, NULL_TREE);
93ca4ba7 205 TREE_NOTHROW (cleanup) = dtor_nothrow (type);
52a11cbf 206
c0700ea5 207 return cleanup;
c7ae64f2
JM
208}
209
210/* This routine creates the cleanup for the current exception. */
72b7eeff 211
c7ae64f2 212static void
5cc3d3b8 213push_eh_cleanup (tree type)
c7ae64f2 214{
52a11cbf 215 finish_decl_cleanup (NULL_TREE, do_end_catch (type));
f4a23343
JM
216}
217
e97f22c9
TT
218/* Return nonzero value if DECL is a Java type suitable for catch or
219 throw. */
220
52a11cbf 221static bool
5cc3d3b8 222decl_is_java_type (tree decl, int err)
e97f22c9 223{
52a11cbf
RH
224 bool r = (TREE_CODE (decl) == POINTER_TYPE
225 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
226 && TYPE_FOR_JAVA (TREE_TYPE (decl)));
e97f22c9
TT
227
228 if (err)
229 {
230 if (TREE_CODE (decl) == REFERENCE_TYPE
231 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
232 && TYPE_FOR_JAVA (TREE_TYPE (decl)))
233 {
234 /* Can't throw a reference. */
33bd39a2 235 error ("type `%T' is disallowed in Java `throw' or `catch'",
e97f22c9
TT
236 decl);
237 }
238
239 if (r)
240 {
241 tree jthrow_node
242 = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
400500c4 243
e97f22c9 244 if (jthrow_node == NULL_TREE)
400500c4
RK
245 fatal_error
246 ("call to Java `catch' or `throw' with `jthrowable' undefined");
247
e97f22c9
TT
248 jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
249
250 if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
251 {
252 /* Thrown object must be a Throwable. */
33bd39a2 253 error ("type `%T' is not derived from `java::lang::Throwable'",
e97f22c9
TT
254 TREE_TYPE (decl));
255 }
256 }
257 }
258
259 return r;
260}
261
1f730ff7
ZW
262/* Select the personality routine to be used for exception handling,
263 or issue an error if we need two different ones in the same
264 translation unit.
265 ??? At present eh_personality_libfunc is set to
266 __gxx_personality_(sj|v)0 in init_exception_processing - should it
267 be done here instead? */
268void
5cc3d3b8 269choose_personality_routine (enum languages lang)
52a11cbf
RH
270{
271 static enum {
272 chose_none,
273 chose_cpp,
274 chose_java,
275 gave_error
276 } state;
277
278 switch (state)
279 {
1f730ff7
ZW
280 case gave_error:
281 return;
52a11cbf
RH
282
283 case chose_cpp:
1f730ff7
ZW
284 if (lang != lang_cplusplus)
285 goto give_error;
286 return;
287
52a11cbf 288 case chose_java:
1f730ff7
ZW
289 if (lang != lang_java)
290 goto give_error;
291 return;
292
293 case chose_none:
294 ; /* proceed to language selection */
295 }
296
297 switch (lang)
298 {
299 case lang_cplusplus:
300 state = chose_cpp;
52a11cbf
RH
301 break;
302
1f730ff7
ZW
303 case lang_java:
304 state = chose_java;
305 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
306 ? "__gcj_personality_sj0"
307 : "__gcj_personality_v0");
52a11cbf 308 break;
1f730ff7
ZW
309
310 default:
311 abort ();
52a11cbf 312 }
1f730ff7
ZW
313 return;
314
315 give_error:
316 error ("mixing C++ and Java catches in a single translation unit");
317 state = gave_error;
52a11cbf
RH
318}
319
b35d4555 320/* Initialize the catch parameter DECL. */
6467930b 321
b35d4555 322static void
5cc3d3b8 323initialize_handler_parm (tree decl, tree exp)
8d08fdba 324{
b35d4555
MM
325 tree init;
326 tree init_type;
327
328 /* Make sure we mark the catch param as used, otherwise we'll get a
329 warning about an unused ((anonymous)). */
330 TREE_USED (decl) = 1;
331
52a11cbf
RH
332 /* Figure out the type that the initializer is. Pointers are returned
333 adjusted by value from __cxa_begin_catch. Others are returned by
334 reference. */
b35d4555 335 init_type = TREE_TYPE (decl);
c93586fa 336 if (! TYPE_PTR_P (init_type)
52a11cbf 337 && TREE_CODE (init_type) != REFERENCE_TYPE)
b35d4555
MM
338 init_type = build_reference_type (init_type);
339
1f730ff7
ZW
340 choose_personality_routine (decl_is_java_type (init_type, 0)
341 ? lang_java : lang_cplusplus);
b35d4555
MM
342
343 /* Since pointers are passed by value, initialize a reference to
52a11cbf 344 pointer catch parm with the address of the temporary. */
c93586fa
RS
345 if (TREE_CODE (init_type) == REFERENCE_TYPE
346 && TYPE_PTR_P (TREE_TYPE (init_type)))
b35d4555
MM
347 exp = build_unary_op (ADDR_EXPR, exp, 1);
348
52a11cbf 349 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
b35d4555
MM
350
351 init = convert_from_reference (exp);
352
353 /* If the constructor for the catch parm exits via an exception, we
354 must call terminate. See eh23.C. */
355 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
faf5394a 356 {
b35d4555
MM
357 /* Generate the copy constructor call directly so we can wrap it.
358 See also expand_default_init. */
359 init = ocp_convert (TREE_TYPE (decl), init,
360 CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
52a11cbf 361 init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
faf5394a
MS
362 }
363
b35d4555
MM
364 /* Let `cp_finish_decl' know that this initializer is ok. */
365 DECL_INITIAL (decl) = error_mark_node;
366 decl = pushdecl (decl);
8d2733ca 367
b35d4555 368 start_decl_1 (decl);
cd9f6678 369 cp_finish_decl (decl, init, NULL_TREE,
b35d4555 370 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
5816cb14
AM
371}
372
b35d4555 373/* Call this to start a catch block. DECL is the catch parameter. */
5816cb14 374
b35d4555 375tree
5cc3d3b8 376expand_start_catch_block (tree decl)
5816cb14 377{
52a11cbf
RH
378 tree exp = NULL_TREE;
379 tree type;
380 bool is_java;
5816cb14 381
b35d4555
MM
382 if (! doing_eh (1))
383 return NULL_TREE;
5816cb14 384
b35d4555 385 /* Make sure this declaration is reasonable. */
3c5c0849
MM
386 if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
387 decl = NULL_TREE;
5816cb14 388
52a11cbf
RH
389 if (decl)
390 type = prepare_eh_type (TREE_TYPE (decl));
391 else
392 type = NULL_TREE;
52a11cbf
RH
393
394 is_java = false;
395 if (decl)
e97f22c9 396 {
52a11cbf 397 tree init;
5816cb14 398
52a11cbf
RH
399 if (decl_is_java_type (type, 1))
400 {
401 /* Java only passes object via pointer and doesn't require
402 adjusting. The java object is immediately before the
403 generic exception header. */
404 init = build_exc_ptr ();
405 init = build1 (NOP_EXPR, build_pointer_type (type), init);
406 init = build (MINUS_EXPR, TREE_TYPE (init), init,
407 TYPE_SIZE_UNIT (TREE_TYPE (init)));
3e411c3f 408 init = build_indirect_ref (init, NULL);
52a11cbf
RH
409 is_java = true;
410 }
e97f22c9 411 else
52a11cbf
RH
412 {
413 /* C++ requires that we call __cxa_begin_catch to get the
414 pointer to the actual object. */
415 init = do_begin_catch ();
416 }
417
418 exp = create_temporary_var (ptr_type_node);
419 DECL_REGISTER (exp) = 1;
420 cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
421 finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
e97f22c9
TT
422 }
423 else
52a11cbf
RH
424 finish_expr_stmt (do_begin_catch ());
425
426 /* C++ requires that we call __cxa_end_catch at the end of
427 processing the exception. */
428 if (! is_java)
429 push_eh_cleanup (type);
5816cb14 430
b35d4555 431 if (decl)
52a11cbf 432 initialize_handler_parm (decl, exp);
5816cb14 433
1a6025b4 434 return type;
5816cb14
AM
435}
436
f30432d7 437
8d2733ca
MS
438/* Call this to end a catch block. Its responsible for emitting the
439 code to handle jumping back to the correct place, and for emitting
440 the label to jump to if this catch block didn't match. */
6467930b 441
824b9a4c 442void
5cc3d3b8 443expand_end_catch_block (void)
8d08fdba 444{
f30432d7
MS
445 if (! doing_eh (1))
446 return;
8d2733ca 447
0dde4175
JM
448 /* The exception being handled is rethrown if control reaches the end of
449 a handler of the function-try-block of a constructor or destructor. */
450 if (in_function_try_handler
451 && (DECL_CONSTRUCTOR_P (current_function_decl)
452 || DECL_DESTRUCTOR_P (current_function_decl)))
b35d4555 453 finish_expr_stmt (build_throw (NULL_TREE));
8d2733ca 454}
8d08fdba 455
b35d4555 456tree
5cc3d3b8 457begin_eh_spec_block (void)
f30432d7 458{
52a11cbf
RH
459 tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
460 add_stmt (r);
461 return r;
f30432d7
MS
462}
463
b35d4555 464void
5cc3d3b8 465finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
f30432d7 466{
52a11cbf 467 tree raises;
0c11ada6 468
52a11cbf 469 RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
6c20b7e9 470
52a11cbf
RH
471 /* Strip cv quals, etc, from the specification types. */
472 for (raises = NULL_TREE;
473 raw_raises && TREE_VALUE (raw_raises);
474 raw_raises = TREE_CHAIN (raw_raises))
475 raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
476 raises);
6c20b7e9 477
52a11cbf 478 EH_SPEC_RAISES (eh_spec_block) = raises;
f30432d7
MS
479}
480
52a11cbf 481/* Return a pointer to a buffer for an exception object of type TYPE. */
6467930b 482
52a11cbf 483static tree
5cc3d3b8 484do_allocate_exception (tree type)
8d08fdba 485{
52a11cbf 486 tree fn;
eb448459 487
52a11cbf
RH
488 fn = get_identifier ("__cxa_allocate_exception");
489 if (IDENTIFIER_GLOBAL_VALUE (fn))
490 fn = IDENTIFIER_GLOBAL_VALUE (fn);
491 else
f30432d7 492 {
52a11cbf 493 /* Declare void *__cxa_allocate_exception(size_t). */
c9f8536c 494 tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
52a11cbf 495 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
e00737d2 496 }
52a11cbf
RH
497
498 return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
499 NULL_TREE));
8d08fdba
MS
500}
501
2ac8a0f9
JM
502#if 0
503/* Call __cxa_free_exception from a cleanup. This is never invoked
6f30f1f1 504 directly, but see the comment for stabilize_throw_expr. */
f4a23343 505
c6160f8f 506static tree
5cc3d3b8 507do_free_exception (tree ptr)
f4a23343 508{
52a11cbf 509 tree fn;
f4a23343 510
52a11cbf 511 fn = get_identifier ("__cxa_free_exception");
f4a23343
JM
512 if (IDENTIFIER_GLOBAL_VALUE (fn))
513 fn = IDENTIFIER_GLOBAL_VALUE (fn);
514 else
515 {
52a11cbf
RH
516 /* Declare void __cxa_free_exception (void *). */
517 fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
518 void_list_node));
f4a23343
JM
519 }
520
52a11cbf 521 return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
f4a23343 522}
2ac8a0f9 523#endif
f4a23343 524
6f30f1f1
JM
525/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
526 Called from build_throw via walk_tree_without_duplicates. */
527
528static tree
5cc3d3b8
GDR
529wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
530 void *data ATTRIBUTE_UNUSED)
6f30f1f1
JM
531{
532 tree exp = *tp;
533 tree cleanup;
534
535 /* Don't walk into types. */
536 if (TYPE_P (exp))
537 {
538 *walk_subtrees = 0;
539 return NULL_TREE;
540 }
541 if (TREE_CODE (exp) != TARGET_EXPR)
542 return NULL_TREE;
543
544 cleanup = TARGET_EXPR_CLEANUP (exp);
545 if (cleanup)
546 {
4e8dca1c 547 cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
6f30f1f1
JM
548 TARGET_EXPR_CLEANUP (exp) = cleanup;
549 }
550
551 /* Keep iterating. */
552 return NULL_TREE;
553}
554
555/* Like stabilize_expr, but specifically for a thrown expression. When
556 throwing a temporary class object, we want to construct it directly into
557 the thrown exception, so we look past the TARGET_EXPR and stabilize the
558 arguments of the call instead.
559
560 The case where EXP is a call to a function returning a class is a bit of
561 a grey area in the standard; it's unclear whether or not it should be
562 allowed to throw. I'm going to say no, as that allows us to optimize
563 this case without worrying about deallocating the exception object if it
564 does. The alternatives would be either not optimizing this case, or
565 wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
566 rather than in a MUST_NOT_THROW_EXPR, for this case only. */
567
568static tree
5cc3d3b8 569stabilize_throw_expr (tree exp, tree *initp)
6f30f1f1
JM
570{
571 tree init_expr;
572
573 if (TREE_CODE (exp) == TARGET_EXPR
574 && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
575 && flag_elide_constructors)
576 {
577 tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
578 tree args = TREE_OPERAND (aggr_init, 1);
579 tree newargs = NULL_TREE;
580 tree *p = &newargs;
581
582 init_expr = void_zero_node;
583 for (; args; args = TREE_CHAIN (args))
584 {
bab076f7 585 tree arg = TREE_VALUE (args);
6f30f1f1 586 tree arg_init_expr;
6f30f1f1 587
c246c65d
JM
588 arg = stabilize_expr (arg, &arg_init_expr);
589
590 if (TREE_SIDE_EFFECTS (arg_init_expr))
591 init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
592 arg_init_expr);
bab076f7 593 *p = tree_cons (NULL_TREE, arg, NULL_TREE);
6f30f1f1
JM
594 p = &TREE_CHAIN (*p);
595 }
596 TREE_OPERAND (aggr_init, 1) = newargs;
597 }
598 else
599 {
600 exp = stabilize_expr (exp, &init_expr);
601 }
602
603 *initp = init_expr;
604 return exp;
605}
606
52a11cbf 607/* Build a throw expression. */
6467930b 608
52a11cbf 609tree
5cc3d3b8 610build_throw (tree exp)
8d08fdba 611{
6874c264 612 tree fn;
8d08fdba 613
52a11cbf
RH
614 if (exp == error_mark_node)
615 return exp;
616
617 if (processing_template_decl)
618 return build_min (THROW_EXPR, void_type_node, exp);
619
620 if (exp == null_node)
33bd39a2 621 warning ("throwing NULL, which has integral, not pointer type");
52a11cbf
RH
622
623 if (exp != NULL_TREE)
624 {
625 if (!is_admissible_throw_operand (exp))
626 return error_mark_node;
627 }
628
8d2733ca 629 if (! doing_eh (1))
59ccf49d 630 return error_mark_node;
8d08fdba 631
52a11cbf 632 if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
e97f22c9 633 {
52a11cbf 634 tree fn = get_identifier ("_Jv_Throw");
e97f22c9
TT
635 if (IDENTIFIER_GLOBAL_VALUE (fn))
636 fn = IDENTIFIER_GLOBAL_VALUE (fn);
637 else
638 {
52a11cbf 639 /* Declare void _Jv_Throw (void *). */
0c11ada6
JM
640 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
641 tmp = build_function_type (ptr_type_node, tmp);
c00996a3 642 fn = push_throw_library_fn (fn, tmp);
e97f22c9
TT
643 }
644
52a11cbf 645 exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
e97f22c9
TT
646 }
647 else if (exp)
8d2733ca 648 {
faae18ab 649 tree throw_type;
52a11cbf 650 tree cleanup;
52a11cbf
RH
651 tree object, ptr;
652 tree tmp;
6f30f1f1 653 tree temp_expr, allocate_expr;
52a11cbf
RH
654
655 fn = get_identifier ("__cxa_throw");
656 if (IDENTIFIER_GLOBAL_VALUE (fn))
657 fn = IDENTIFIER_GLOBAL_VALUE (fn);
658 else
659 {
660 /* The CLEANUP_TYPE is the internal type of a destructor. */
661 if (cleanup_type == NULL_TREE)
662 {
663 tmp = void_list_node;
664 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
665 tmp = build_function_type (void_type_node, tmp);
666 cleanup_type = build_pointer_type (tmp);
667 }
668
669 /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */
670 /* ??? Second argument is supposed to be "std::type_info*". */
671 tmp = void_list_node;
672 tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
673 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
674 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
675 tmp = build_function_type (void_type_node, tmp);
676 fn = push_throw_library_fn (fn, tmp);
677 }
59ccf49d 678
a3b49ccd 679 /* throw expression */
e92cc029 680 /* First, decay it. */
f30432d7 681 exp = decay_conversion (exp);
a3b49ccd 682
52a11cbf
RH
683 /* OK, this is kind of wacky. The standard says that we call
684 terminate when the exception handling mechanism, after
685 completing evaluation of the expression to be thrown but
686 before the exception is caught (_except.throw_), calls a
687 user function that exits via an uncaught exception.
688
689 So we have to protect the actual initialization of the
690 exception object with terminate(), but evaluate the
691 expression first. Since there could be temps in the
692 expression, we need to handle that, too. We also expand
693 the call to __cxa_allocate_exception first (which doesn't
694 matter, since it can't throw). */
695
6f30f1f1
JM
696 /* Pre-evaluate the thrown expression first, since if we allocated
697 the space first we would have to deal with cleaning it up if
698 evaluating this expression throws. */
699 exp = stabilize_throw_expr (exp, &temp_expr);
6874c264 700
52a11cbf 701 /* Allocate the space for the exception. */
6f30f1f1
JM
702 allocate_expr = do_allocate_exception (TREE_TYPE (exp));
703 allocate_expr = get_target_expr (allocate_expr);
704 ptr = TARGET_EXPR_SLOT (allocate_expr);
52a11cbf 705 object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
3e411c3f 706 object = build_indirect_ref (object, NULL);
faae18ab 707
6f30f1f1
JM
708 /* And initialize the exception object. */
709 exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
52a11cbf 710 if (exp == error_mark_node)
6f30f1f1
JM
711 {
712 error (" in thrown expression");
713 return error_mark_node;
714 }
f4a23343 715
4e8dca1c 716 exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
6f30f1f1
JM
717 /* Prepend the allocation. */
718 exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
719 if (temp_expr != void_zero_node)
720 {
721 /* Prepend the calculation of the throw expression. Also, force
722 any cleanups from the expression to be evaluated here so that
723 we don't have to do them during unwinding. But first wrap
724 them in MUST_NOT_THROW_EXPR, since they are run after the
725 exception object is initialized. */
726 walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
727 exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
728 exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
729 }
72b7eeff 730
52a11cbf 731 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
f4a23343 732
52a11cbf
RH
733 if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
734 {
735 cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
736 complete_dtor_identifier, 0);
50ad9642 737 cleanup = BASELINK_FUNCTIONS (cleanup);
52a11cbf 738 mark_used (cleanup);
dffd7eb6 739 cxx_mark_addressable (cleanup);
52a11cbf
RH
740 /* Pretend it's a normal function. */
741 cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
f30432d7 742 }
52a11cbf 743 else
6874c264
JM
744 {
745 cleanup = build_int_2 (0, 0);
746 TREE_TYPE (cleanup) = cleanup_type;
747 }
72b7eeff 748
52a11cbf
RH
749 tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
750 tmp = tree_cons (NULL_TREE, throw_type, tmp);
751 tmp = tree_cons (NULL_TREE, ptr, tmp);
52a11cbf 752 /* ??? Indicate that this function call throws throw_type. */
6f30f1f1 753 tmp = build_function_call (fn, tmp);
72b7eeff 754
6f30f1f1
JM
755 /* Tack on the initialization stuff. */
756 exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
8d2733ca
MS
757 }
758 else
a3b49ccd 759 {
52a11cbf 760 /* Rethrow current exception. */
6874c264 761
52a11cbf 762 tree fn = get_identifier ("__cxa_rethrow");
6874c264
JM
763 if (IDENTIFIER_GLOBAL_VALUE (fn))
764 fn = IDENTIFIER_GLOBAL_VALUE (fn);
765 else
52a11cbf
RH
766 {
767 /* Declare void __cxa_rethrow (void). */
768 fn = push_throw_library_fn
769 (fn, build_function_type (void_type_node, void_list_node));
770 }
6874c264 771
6f30f1f1
JM
772 /* ??? Indicate that this function call allows exceptions of the type
773 of the enclosing catch block (if known). */
6874c264 774 exp = build_function_call (fn, NULL_TREE);
a3b49ccd 775 }
8d2733ca 776
52a11cbf 777 exp = build1 (THROW_EXPR, void_type_node, exp);
02020185 778
52a11cbf 779 return exp;
8d08fdba 780}
4cfbc546
NS
781
782/* Make sure TYPE is complete, pointer to complete, reference to
783 complete, or pointer to cv void. Issue diagnostic on failure.
838dfd8a 784 Return the zero on failure and nonzero on success. FROM can be
4cfbc546
NS
785 the expr or decl from whence TYPE came, if available. */
786
787static int
5cc3d3b8 788complete_ptr_ref_or_void_ptr_p (tree type, tree from)
4cfbc546
NS
789{
790 int is_ptr;
791
792 /* Check complete. */
793 type = complete_type_or_else (type, from);
794 if (!type)
795 return 0;
796
797 /* Or a pointer or ref to one, or cv void *. */
798 is_ptr = TREE_CODE (type) == POINTER_TYPE;
799 if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
800 {
801 tree core = TREE_TYPE (type);
802
b72801e2 803 if (is_ptr && VOID_TYPE_P (core))
4cfbc546
NS
804 /* OK */;
805 else if (!complete_type_or_else (core, from))
806 return 0;
807 }
808 return 1;
809}
810
d064d75a
GDR
811/* Return truth-value if EXPRESSION is admissible in throw-expression,
812 i.e. if it is not of incomplete type or a pointer/reference to such
813 a type or of an abstract class type. */
814
815static bool
5cc3d3b8 816is_admissible_throw_operand (tree expr)
d064d75a
GDR
817{
818 tree type = TREE_TYPE (expr);
819
820 /* 15.1/4 [...] The type of the throw-expression shall not be an
821 incomplete type, or a pointer or a reference to an incomplete
822 type, other than void*, const void*, volatile void*, or
823 const volatile void*. Except for these restriction and the
824 restrictions on type matching mentioned in 15.3, the operand
825 of throw is treated exactly as a function argument in a call
826 (5.2.2) or the operand of a return statement. */
827 if (!complete_ptr_ref_or_void_ptr_p (type, expr))
828 return false;
829
830 /* 10.4/3 An abstract class shall not be used as a parameter type,
831 as a function return type or as type of an explicit
832 conversion. */
833 else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
834 {
33bd39a2 835 error ("expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
d064d75a
GDR
836 return false;
837 }
838
839 return true;
840}
841
1660cb3a
JM
842/* Returns nonzero if FN is a declaration of a standard C library
843 function which is known not to throw.
844
845 [lib.res.on.exception.handling]: None of the functions from the
846 Standard C library shall report an error by throwing an
847 exception, unless it calls a program-supplied function that
848 throws an exception. */
849
850#include "cfns.h"
851
852int
5cc3d3b8 853nothrow_libfn_p (tree fn)
1660cb3a
JM
854{
855 tree id;
856
857 if (TREE_PUBLIC (fn)
858 && DECL_EXTERNAL (fn)
92643fea 859 && DECL_NAMESPACE_SCOPE_P (fn)
eb68cb58 860 && DECL_EXTERN_C_P (fn))
1660cb3a
JM
861 /* OK */;
862 else
863 /* Can't be a C library function. */
864 return 0;
865
866 id = DECL_ASSEMBLER_NAME (fn);
867 return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
868}
2bc9f1d1
JM
869
870/* Returns nonzero if an exception of type FROM will be caught by a
871 handler for type TO, as per [except.handle]. */
872
873static int
5cc3d3b8 874can_convert_eh (tree to, tree from)
2bc9f1d1
JM
875{
876 if (TREE_CODE (to) == REFERENCE_TYPE)
877 to = TREE_TYPE (to);
878 if (TREE_CODE (from) == REFERENCE_TYPE)
879 from = TREE_TYPE (from);
880
881 if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
882 {
883 to = TREE_TYPE (to);
884 from = TREE_TYPE (from);
885
886 if (! at_least_as_qualified_p (to, from))
887 return 0;
888
889 if (TREE_CODE (to) == VOID_TYPE)
890 return 1;
891
892 /* else fall through */
893 }
894
2d46ec83 895 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
2bc9f1d1
JM
896 && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
897 return 1;
898
899 return 0;
900}
901
902/* Check whether any of HANDLERS are shadowed by another handler accepting
903 TYPE. Note that the shadowing may not be complete; even if an exception
904 of type B would be caught by a handler for A, there could be a derived
905 class C for which A is an ambiguous base but B is not, so the handler
906 for B would catch an exception of type C. */
907
908static void
5cc3d3b8 909check_handlers_1 (tree master, tree handlers)
2bc9f1d1
JM
910{
911 tree type = TREE_TYPE (master);
912 tree handler;
913
914 for (handler = handlers; handler; handler = TREE_CHAIN (handler))
915 if (TREE_TYPE (handler)
916 && can_convert_eh (type, TREE_TYPE (handler)))
917 {
918 lineno = STMT_LINENO (handler);
33bd39a2 919 warning ("exception of type `%T' will be caught",
2bc9f1d1
JM
920 TREE_TYPE (handler));
921 lineno = STMT_LINENO (master);
33bd39a2 922 warning (" by earlier handler for `%T'", type);
2bc9f1d1
JM
923 break;
924 }
925}
926
927/* Given a chain of HANDLERs, make sure that they're OK. */
928
929void
5cc3d3b8 930check_handlers (tree handlers)
2bc9f1d1
JM
931{
932 tree handler;
933 int save_line = lineno;
934 for (handler = handlers; handler; handler = TREE_CHAIN (handler))
935 {
936 if (TREE_CHAIN (handler) == NULL_TREE)
937 /* No more handlers; nothing to shadow. */;
938 else if (TREE_TYPE (handler) == NULL_TREE)
939 {
940 lineno = STMT_LINENO (handler);
33bd39a2 941 pedwarn
2bc9f1d1
JM
942 ("`...' handler must be the last handler for its try block");
943 }
944 else
945 check_handlers_1 (handler, TREE_CHAIN (handler));
946 }
947 lineno = save_line;
948}
This page took 1.150105 seconds and 5 git commands to generate.