Commit 0dde4175 by Jason Merrill Committed by Jason Merrill

semantics.c (begin_function_try_block, [...]): New fns.

	* semantics.c (begin_function_try_block, finish_function_try_block,
	finish_function_handler_sequence): New fns.
	* parse.y (function_try_block): Use them.
	* pt.c (instantiate_decl): Likewise.

	* cp-tree.h: Declare in_function_try_handler.
	* decl.c: Define it.
	(start_function): Clear it.
	(struct cp_function, push_cp_function_context): Save it.
	(pop_cp_function_context): Restore it.
	* parse.y (function_try_block): Set and clear it.
	* except.c (expand_end_catch_block): Rethrow if we reach the end
	of a function-try-block handler in a ctor or dtor.
	* typeck.c (c_expand_return): Complain about returning from a
	function-try-block handler of a ctor.

	* parse.y (function_try_block): Call end_protect_partials
	before expand_start_all_catch.

From-SVN: r28624
parent fb20fc45
1999-08-09 Jason Merrill <jason@yorick.cygnus.com>
* semantics.c (begin_function_try_block, finish_function_try_block,
finish_function_handler_sequence): New fns.
* parse.y (function_try_block): Use them.
* pt.c (instantiate_decl): Likewise.
* cp-tree.h: Declare in_function_try_handler.
* decl.c: Define it.
(start_function): Clear it.
(struct cp_function, push_cp_function_context): Save it.
(pop_cp_function_context): Restore it.
* parse.y (function_try_block): Set and clear it.
* except.c (expand_end_catch_block): Rethrow if we reach the end
of a function-try-block handler in a ctor or dtor.
* typeck.c (c_expand_return): Complain about returning from a
function-try-block handler of a ctor.
* parse.y (function_try_block): Call end_protect_partials
before expand_start_all_catch.
1999-08-08 Jason Merrill <jason@yorick.cygnus.com> 1999-08-08 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (struct binding_level): Add eh_region field. * decl.c (struct binding_level): Add eh_region field.
......
...@@ -2290,6 +2290,8 @@ extern tree tag_identifier; ...@@ -2290,6 +2290,8 @@ extern tree tag_identifier;
extern tree vt_off_identifier; extern tree vt_off_identifier;
extern tree empty_except_spec; extern tree empty_except_spec;
extern int in_function_try_handler;
/* A node that is a list (length 1) of error_mark_nodes. */ /* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list; extern tree error_mark_list;
...@@ -3381,6 +3383,9 @@ extern void finish_goto_stmt PROTO((tree)); ...@@ -3381,6 +3383,9 @@ extern void finish_goto_stmt PROTO((tree));
extern tree begin_try_block PROTO((void)); extern tree begin_try_block PROTO((void));
extern void finish_try_block PROTO((tree)); extern void finish_try_block PROTO((tree));
extern void finish_handler_sequence PROTO((tree)); extern void finish_handler_sequence PROTO((tree));
extern tree begin_function_try_block PROTO((void));
extern void finish_function_try_block PROTO((tree));
extern void finish_function_handler_sequence PROTO((tree));
extern tree begin_handler PROTO((void)); extern tree begin_handler PROTO((void));
extern void finish_handler_parms PROTO((tree)); extern void finish_handler_parms PROTO((tree));
extern void finish_handler PROTO((tree)); extern void finish_handler PROTO((tree));
......
...@@ -288,7 +288,7 @@ tree va_list_type_node; ...@@ -288,7 +288,7 @@ tree va_list_type_node;
static tree global_type_node; static tree global_type_node;
/* Namespace std. */ /* Namespace std. */
int in_std = 0; int in_std;
/* Expect only namespace names now. */ /* Expect only namespace names now. */
static int only_namespace_names; static int only_namespace_names;
...@@ -339,6 +339,9 @@ tree vt_off_identifier; ...@@ -339,6 +339,9 @@ tree vt_off_identifier;
/* Exception specifier used for throw(). */ /* Exception specifier used for throw(). */
tree empty_except_spec; tree empty_except_spec;
/* Nonzero if we're in a handler for a function-try-block. */
int in_function_try_handler;
struct named_label_list struct named_label_list
{ {
struct binding_level *binding_level; struct binding_level *binding_level;
...@@ -12982,6 +12985,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -12982,6 +12985,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
current_member_init_list = NULL_TREE; current_member_init_list = NULL_TREE;
ctor_label = dtor_label = NULL_TREE; ctor_label = dtor_label = NULL_TREE;
static_labelno = 0; static_labelno = 0;
in_function_try_handler = 0;
clear_temp_name (); clear_temp_name ();
...@@ -14622,6 +14626,7 @@ struct cp_function ...@@ -14622,6 +14626,7 @@ struct cp_function
struct cp_function *next; struct cp_function *next;
struct binding_level *binding_level; struct binding_level *binding_level;
int static_labelno; int static_labelno;
int in_function_try_handler;
}; };
static struct cp_function *cp_function_chain; static struct cp_function *cp_function_chain;
...@@ -14664,6 +14669,7 @@ push_cp_function_context (context) ...@@ -14664,6 +14669,7 @@ push_cp_function_context (context)
p->current_class_ptr = current_class_ptr; p->current_class_ptr = current_class_ptr;
p->current_class_ref = current_class_ref; p->current_class_ref = current_class_ref;
p->static_labelno = static_labelno; p->static_labelno = static_labelno;
p->in_function_try_handler = in_function_try_handler;
} }
/* Restore the variables used during compilation of a C++ function. */ /* Restore the variables used during compilation of a C++ function. */
...@@ -14706,6 +14712,7 @@ pop_cp_function_context (context) ...@@ -14706,6 +14712,7 @@ pop_cp_function_context (context)
current_class_ptr = p->current_class_ptr; current_class_ptr = p->current_class_ptr;
current_class_ref = p->current_class_ref; current_class_ref = p->current_class_ref;
static_labelno = p->static_labelno; static_labelno = p->static_labelno;
in_function_try_handler = p->in_function_try_handler;
free (p); free (p);
} }
......
...@@ -698,6 +698,13 @@ expand_end_catch_block () ...@@ -698,6 +698,13 @@ expand_end_catch_block ()
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
/* The exception being handled is rethrown if control reaches the end of
a handler of the function-try-block of a constructor or destructor. */
if (in_function_try_handler
&& (DECL_CONSTRUCTOR_P (current_function_decl)
|| DECL_DESTRUCTOR_P (current_function_decl)))
expand_throw (NULL_TREE);
/* Cleanup the EH parameter. */ /* Cleanup the EH parameter. */
expand_end_bindings (getdecls (), kept_level_p (), 0); expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
......
...@@ -720,18 +720,18 @@ static const short yyrline[] = { 0, ...@@ -720,18 +720,18 @@ static const short yyrline[] = { 0,
3299, 3301, 3302, 3304, 3309, 3311, 3313, 3315, 3317, 3320, 3299, 3301, 3302, 3304, 3309, 3311, 3313, 3315, 3317, 3320,
3321, 3323, 3326, 3327, 3330, 3330, 3333, 3333, 3336, 3336, 3321, 3323, 3326, 3327, 3330, 3330, 3333, 3333, 3336, 3336,
3338, 3340, 3342, 3344, 3350, 3356, 3359, 3362, 3368, 3370, 3338, 3340, 3342, 3344, 3350, 3356, 3359, 3362, 3368, 3370,
3372, 3376, 3378, 3379, 3380, 3382, 3385, 3392, 3397, 3403, 3372, 3376, 3378, 3379, 3380, 3382, 3385, 3388, 3391, 3397,
3407, 3409, 3412, 3414, 3417, 3421, 3423, 3426, 3428, 3431, 3401, 3403, 3406, 3408, 3411, 3415, 3417, 3420, 3422, 3425,
3448, 3454, 3462, 3464, 3466, 3470, 3473, 3474, 3482, 3486, 3442, 3448, 3456, 3458, 3460, 3464, 3467, 3468, 3476, 3480,
3490, 3493, 3494, 3500, 3503, 3506, 3508, 3512, 3517, 3520, 3484, 3487, 3488, 3494, 3497, 3500, 3502, 3506, 3511, 3514,
3530, 3535, 3536, 3543, 3546, 3549, 3551, 3554, 3556, 3566, 3524, 3529, 3530, 3537, 3540, 3543, 3545, 3548, 3550, 3560,
3580, 3584, 3587, 3589, 3593, 3597, 3600, 3603, 3605, 3609, 3574, 3578, 3581, 3583, 3587, 3591, 3594, 3597, 3599, 3603,
3611, 3618, 3625, 3628, 3632, 3636, 3640, 3646, 3650, 3655, 3605, 3612, 3619, 3622, 3626, 3630, 3634, 3640, 3644, 3649,
3657, 3660, 3665, 3671, 3682, 3685, 3687, 3691, 3699, 3702, 3651, 3654, 3659, 3665, 3676, 3679, 3681, 3685, 3693, 3696,
3706, 3709, 3711, 3713, 3719, 3724, 3727, 3729, 3731, 3733, 3700, 3703, 3705, 3707, 3713, 3718, 3721, 3723, 3725, 3727,
3735, 3737, 3739, 3741, 3743, 3745, 3747, 3749, 3751, 3753, 3729, 3731, 3733, 3735, 3737, 3739, 3741, 3743, 3745, 3747,
3755, 3757, 3759, 3761, 3763, 3765, 3767, 3769, 3771, 3773, 3749, 3751, 3753, 3755, 3757, 3759, 3761, 3763, 3765, 3767,
3775, 3777, 3779, 3781, 3783, 3785, 3787, 3789, 3792, 3794 3769, 3771, 3773, 3775, 3777, 3779, 3781, 3783, 3786, 3788
}; };
#endif #endif
...@@ -7722,61 +7722,55 @@ case 765: ...@@ -7722,61 +7722,55 @@ case 765:
break;} break;}
case 767: case 767:
#line 3387 "parse.y" #line 3387 "parse.y"
{ { yyval.ttype = begin_function_try_block (); ;
if (! current_function_parms_stored)
store_parm_decls ();
expand_start_early_try_stmts ();
;
break;} break;}
case 768: case 768:
#line 3393 "parse.y" #line 3389 "parse.y"
{ { finish_function_try_block (yyvsp[-2].ttype); ;
expand_start_all_catch ();
;
break;} break;}
case 769: case 769:
#line 3397 "parse.y" #line 3391 "parse.y"
{ {
expand_end_all_catch (); finish_function_handler_sequence (yyvsp[-4].ttype);
yyval.itype = yyvsp[-3].itype; yyval.itype = yyvsp[-3].itype;
; ;
break;} break;}
case 770: case 770:
#line 3405 "parse.y" #line 3399 "parse.y"
{ yyval.ttype = begin_try_block (); ; { yyval.ttype = begin_try_block (); ;
break;} break;}
case 771: case 771:
#line 3407 "parse.y" #line 3401 "parse.y"
{ finish_try_block (yyvsp[-1].ttype); ; { finish_try_block (yyvsp[-1].ttype); ;
break;} break;}
case 772: case 772:
#line 3409 "parse.y" #line 3403 "parse.y"
{ finish_handler_sequence (yyvsp[-3].ttype); ; { finish_handler_sequence (yyvsp[-3].ttype); ;
break;} break;}
case 775: case 775:
#line 3419 "parse.y" #line 3413 "parse.y"
{ yyval.ttype = begin_handler(); ; { yyval.ttype = begin_handler(); ;
break;} break;}
case 776: case 776:
#line 3421 "parse.y" #line 3415 "parse.y"
{ finish_handler_parms (yyvsp[-1].ttype); ; { finish_handler_parms (yyvsp[-1].ttype); ;
break;} break;}
case 777: case 777:
#line 3423 "parse.y" #line 3417 "parse.y"
{ finish_handler (yyvsp[-3].ttype); ; { finish_handler (yyvsp[-3].ttype); ;
break;} break;}
case 780: case 780:
#line 3433 "parse.y" #line 3427 "parse.y"
{ expand_start_catch_block (NULL_TREE, NULL_TREE); ; { expand_start_catch_block (NULL_TREE, NULL_TREE); ;
break;} break;}
case 781: case 781:
#line 3449 "parse.y" #line 3443 "parse.y"
{ check_for_new_type ("inside exception declarations", yyvsp[-1].ftype); { check_for_new_type ("inside exception declarations", yyvsp[-1].ftype);
expand_start_catch_block (TREE_PURPOSE (yyvsp[-1].ftype.t), expand_start_catch_block (TREE_PURPOSE (yyvsp[-1].ftype.t),
TREE_VALUE (yyvsp[-1].ftype.t)); ; TREE_VALUE (yyvsp[-1].ftype.t)); ;
break;} break;}
case 782: case 782:
#line 3456 "parse.y" #line 3450 "parse.y"
{ tree label; { tree label;
do_label: do_label:
label = define_label (input_filename, lineno, yyvsp[-1].ttype); label = define_label (input_filename, lineno, yyvsp[-1].ttype);
...@@ -7785,98 +7779,98 @@ case 782: ...@@ -7785,98 +7779,98 @@ case 782:
; ;
break;} break;}
case 783: case 783:
#line 3463 "parse.y" #line 3457 "parse.y"
{ goto do_label; ; { goto do_label; ;
break;} break;}
case 784: case 784:
#line 3465 "parse.y" #line 3459 "parse.y"
{ goto do_label; ; { goto do_label; ;
break;} break;}
case 785: case 785:
#line 3467 "parse.y" #line 3461 "parse.y"
{ goto do_label; ; { goto do_label; ;
break;} break;}
case 786: case 786:
#line 3472 "parse.y" #line 3466 "parse.y"
{ if (yyvsp[-1].ttype) cplus_expand_expr_stmt (yyvsp[-1].ttype); ; { if (yyvsp[-1].ttype) cplus_expand_expr_stmt (yyvsp[-1].ttype); ;
break;} break;}
case 788: case 788:
#line 3475 "parse.y" #line 3469 "parse.y"
{ if (pedantic) { if (pedantic)
pedwarn ("ANSI C++ forbids compound statements inside for initializations"); pedwarn ("ANSI C++ forbids compound statements inside for initializations");
; ;
break;} break;}
case 789: case 789:
#line 3484 "parse.y" #line 3478 "parse.y"
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
yyval.ttype = NULL_TREE; ; yyval.ttype = NULL_TREE; ;
break;} break;}
case 790: case 790:
#line 3487 "parse.y" #line 3481 "parse.y"
{ emit_line_note (input_filename, lineno); ; { emit_line_note (input_filename, lineno); ;
break;} break;}
case 791: case 791:
#line 3492 "parse.y" #line 3486 "parse.y"
{ yyval.ttype = NULL_TREE; ; { yyval.ttype = NULL_TREE; ;
break;} break;}
case 793: case 793:
#line 3495 "parse.y" #line 3489 "parse.y"
{ yyval.ttype = NULL_TREE; ; { yyval.ttype = NULL_TREE; ;
break;} break;}
case 794: case 794:
#line 3502 "parse.y" #line 3496 "parse.y"
{ yyval.ttype = NULL_TREE; ; { yyval.ttype = NULL_TREE; ;
break;} break;}
case 797: case 797:
#line 3509 "parse.y" #line 3503 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ; { yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ;
break;} break;}
case 798: case 798:
#line 3514 "parse.y" #line 3508 "parse.y"
{ yyval.ttype = build_tree_list (yyval.ttype, yyvsp[-1].ttype); ; { yyval.ttype = build_tree_list (yyval.ttype, yyvsp[-1].ttype); ;
break;} break;}
case 799: case 799:
#line 3519 "parse.y" #line 3513 "parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyval.ttype, NULL_TREE); ; { yyval.ttype = tree_cons (NULL_TREE, yyval.ttype, NULL_TREE); ;
break;} break;}
case 800: case 800:
#line 3521 "parse.y" #line 3515 "parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ; { yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ;
break;} break;}
case 801: case 801:
#line 3532 "parse.y" #line 3526 "parse.y"
{ {
yyval.ttype = empty_parms(); yyval.ttype = empty_parms();
; ;
break;} break;}
case 803: case 803:
#line 3537 "parse.y" #line 3531 "parse.y"
{ yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[0].ftype.t), 0); { yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[0].ftype.t), 0);
check_for_new_type ("inside parameter list", yyvsp[0].ftype); ; check_for_new_type ("inside parameter list", yyvsp[0].ftype); ;
break;} break;}
case 804: case 804:
#line 3545 "parse.y" #line 3539 "parse.y"
{ yyval.ttype = finish_parmlist (yyval.ttype, 0); ; { yyval.ttype = finish_parmlist (yyval.ttype, 0); ;
break;} break;}
case 805: case 805:
#line 3547 "parse.y" #line 3541 "parse.y"
{ yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ; { yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ;
break;} break;}
case 806: case 806:
#line 3550 "parse.y" #line 3544 "parse.y"
{ yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ; { yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ;
break;} break;}
case 807: case 807:
#line 3552 "parse.y" #line 3546 "parse.y"
{ yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, { yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE,
yyvsp[-1].ftype.t), 1); ; yyvsp[-1].ftype.t), 1); ;
break;} break;}
case 808: case 808:
#line 3555 "parse.y" #line 3549 "parse.y"
{ yyval.ttype = finish_parmlist (NULL_TREE, 1); ; { yyval.ttype = finish_parmlist (NULL_TREE, 1); ;
break;} break;}
case 809: case 809:
#line 3557 "parse.y" #line 3551 "parse.y"
{ {
/* This helps us recover from really nasty /* This helps us recover from really nasty
parse errors, for example, a missing right parse errors, for example, a missing right
...@@ -7888,7 +7882,7 @@ case 809: ...@@ -7888,7 +7882,7 @@ case 809:
; ;
break;} break;}
case 810: case 810:
#line 3567 "parse.y" #line 3561 "parse.y"
{ {
/* This helps us recover from really nasty /* This helps us recover from really nasty
parse errors, for example, a missing right parse errors, for example, a missing right
...@@ -7901,99 +7895,99 @@ case 810: ...@@ -7901,99 +7895,99 @@ case 810:
; ;
break;} break;}
case 811: case 811:
#line 3582 "parse.y" #line 3576 "parse.y"
{ maybe_snarf_defarg (); ; { maybe_snarf_defarg (); ;
break;} break;}
case 812: case 812:
#line 3584 "parse.y" #line 3578 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ; { yyval.ttype = yyvsp[0].ttype; ;
break;} break;}
case 815: case 815:
#line 3595 "parse.y" #line 3589 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[0].ftype); { check_for_new_type ("in a parameter list", yyvsp[0].ftype);
yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); ; yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); ;
break;} break;}
case 816: case 816:
#line 3598 "parse.y" #line 3592 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[-1].ftype); { check_for_new_type ("in a parameter list", yyvsp[-1].ftype);
yyval.ttype = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); ; yyval.ttype = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); ;
break;} break;}
case 817: case 817:
#line 3601 "parse.y" #line 3595 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[0].ftype); { check_for_new_type ("in a parameter list", yyvsp[0].ftype);
yyval.ttype = chainon (yyval.ttype, yyvsp[0].ftype.t); ; yyval.ttype = chainon (yyval.ttype, yyvsp[0].ftype.t); ;
break;} break;}
case 818: case 818:
#line 3604 "parse.y" #line 3598 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; { yyval.ttype = chainon (yyval.ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;} break;}
case 819: case 819:
#line 3606 "parse.y" #line 3600 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, build_tree_list (yyvsp[0].ttype, yyvsp[-2].ttype)); ; { yyval.ttype = chainon (yyval.ttype, build_tree_list (yyvsp[0].ttype, yyvsp[-2].ttype)); ;
break;} break;}
case 821: case 821:
#line 3612 "parse.y" #line 3606 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[-1].ftype); { check_for_new_type ("in a parameter list", yyvsp[-1].ftype);
yyval.ttype = build_tree_list (NULL_TREE, yyvsp[-1].ftype.t); ; yyval.ttype = build_tree_list (NULL_TREE, yyvsp[-1].ftype.t); ;
break;} break;}
case 822: case 822:
#line 3622 "parse.y" #line 3616 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t); { tree specs = strip_attrs (yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag;
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); ; yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); ;
break;} break;}
case 823: case 823:
#line 3626 "parse.y" #line 3620 "parse.y"
{ yyval.ftype.t = build_tree_list (yyvsp[-1].ftype.t, yyvsp[0].ttype); { yyval.ftype.t = build_tree_list (yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;} break;}
case 824: case 824:
#line 3629 "parse.y" #line 3623 "parse.y"
{ yyval.ftype.t = build_tree_list (build_decl_list (NULL_TREE, yyvsp[-1].ftype.t), { yyval.ftype.t = build_tree_list (build_decl_list (NULL_TREE, yyvsp[-1].ftype.t),
yyvsp[0].ttype); yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;} break;}
case 825: case 825:
#line 3633 "parse.y" #line 3627 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t); { tree specs = strip_attrs (yyvsp[-1].ftype.t);
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;} break;}
case 826: case 826:
#line 3637 "parse.y" #line 3631 "parse.y"
{ tree specs = strip_attrs (yyvsp[0].ftype.t); { tree specs = strip_attrs (yyvsp[0].ftype.t);
yyval.ftype.t = build_tree_list (specs, NULL_TREE); yyval.ftype.t = build_tree_list (specs, NULL_TREE);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;} break;}
case 827: case 827:
#line 3641 "parse.y" #line 3635 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ttype); { tree specs = strip_attrs (yyvsp[-1].ttype);
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype);
yyval.ftype.new_type_flag = 0; ; yyval.ftype.new_type_flag = 0; ;
break;} break;}
case 828: case 828:
#line 3648 "parse.y" #line 3642 "parse.y"
{ yyval.ftype.t = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); { yyval.ftype.t = build_tree_list (NULL_TREE, yyvsp[0].ftype.t);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;} break;}
case 829: case 829:
#line 3651 "parse.y" #line 3645 "parse.y"
{ yyval.ftype.t = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); { yyval.ftype.t = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;} break;}
case 832: case 832:
#line 3662 "parse.y" #line 3656 "parse.y"
{ see_typename (); ; { see_typename (); ;
break;} break;}
case 833: case 833:
#line 3667 "parse.y" #line 3661 "parse.y"
{ {
error ("type specifier omitted for parameter"); error ("type specifier omitted for parameter");
yyval.ttype = build_tree_list (integer_type_node, NULL_TREE); yyval.ttype = build_tree_list (integer_type_node, NULL_TREE);
; ;
break;} break;}
case 834: case 834:
#line 3672 "parse.y" #line 3666 "parse.y"
{ {
error ("type specifier omitted for parameter"); error ("type specifier omitted for parameter");
if (TREE_CODE (yyval.ttype) == SCOPE_REF if (TREE_CODE (yyval.ttype) == SCOPE_REF
...@@ -8004,192 +7998,192 @@ case 834: ...@@ -8004,192 +7998,192 @@ case 834:
; ;
break;} break;}
case 835: case 835:
#line 3684 "parse.y" #line 3678 "parse.y"
{ yyval.ttype = NULL_TREE; ; { yyval.ttype = NULL_TREE; ;
break;} break;}
case 836: case 836:
#line 3686 "parse.y" #line 3680 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ; { yyval.ttype = yyvsp[-1].ttype; ;
break;} break;}
case 837: case 837:
#line 3688 "parse.y" #line 3682 "parse.y"
{ yyval.ttype = empty_except_spec; ; { yyval.ttype = empty_except_spec; ;
break;} break;}
case 838: case 838:
#line 3693 "parse.y" #line 3687 "parse.y"
{ {
check_for_new_type ("exception specifier", yyvsp[0].ftype); check_for_new_type ("exception specifier", yyvsp[0].ftype);
yyval.ttype = groktypename (yyvsp[0].ftype.t); yyval.ttype = groktypename (yyvsp[0].ftype.t);
; ;
break;} break;}
case 839: case 839:
#line 3701 "parse.y" #line 3695 "parse.y"
{ yyval.ttype = add_exception_specifier (NULL_TREE, yyvsp[0].ttype, 1); ; { yyval.ttype = add_exception_specifier (NULL_TREE, yyvsp[0].ttype, 1); ;
break;} break;}
case 840: case 840:
#line 3703 "parse.y" #line 3697 "parse.y"
{ yyval.ttype = add_exception_specifier (yyvsp[-2].ttype, yyvsp[0].ttype, 1); ; { yyval.ttype = add_exception_specifier (yyvsp[-2].ttype, yyvsp[0].ttype, 1); ;
break;} break;}
case 841: case 841:
#line 3708 "parse.y" #line 3702 "parse.y"
{ yyval.ttype = NULL_TREE; ; { yyval.ttype = NULL_TREE; ;
break;} break;}
case 842: case 842:
#line 3710 "parse.y" #line 3704 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; { yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;} break;}
case 843: case 843:
#line 3712 "parse.y" #line 3706 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; { yyval.ttype = make_reference_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;} break;}
case 844: case 844:
#line 3714 "parse.y" #line 3708 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); { tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg); yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
; ;
break;} break;}
case 845: case 845:
#line 3721 "parse.y" #line 3715 "parse.y"
{ got_scope = NULL_TREE; ; { got_scope = NULL_TREE; ;
break;} break;}
case 846: case 846:
#line 3726 "parse.y" #line 3720 "parse.y"
{ yyval.ttype = ansi_opname[MULT_EXPR]; ; { yyval.ttype = ansi_opname[MULT_EXPR]; ;
break;} break;}
case 847: case 847:
#line 3728 "parse.y" #line 3722 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_DIV_EXPR]; ; { yyval.ttype = ansi_opname[TRUNC_DIV_EXPR]; ;
break;} break;}
case 848: case 848:
#line 3730 "parse.y" #line 3724 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_MOD_EXPR]; ; { yyval.ttype = ansi_opname[TRUNC_MOD_EXPR]; ;
break;} break;}
case 849: case 849:
#line 3732 "parse.y" #line 3726 "parse.y"
{ yyval.ttype = ansi_opname[PLUS_EXPR]; ; { yyval.ttype = ansi_opname[PLUS_EXPR]; ;
break;} break;}
case 850: case 850:
#line 3734 "parse.y" #line 3728 "parse.y"
{ yyval.ttype = ansi_opname[MINUS_EXPR]; ; { yyval.ttype = ansi_opname[MINUS_EXPR]; ;
break;} break;}
case 851: case 851:
#line 3736 "parse.y" #line 3730 "parse.y"
{ yyval.ttype = ansi_opname[BIT_AND_EXPR]; ; { yyval.ttype = ansi_opname[BIT_AND_EXPR]; ;
break;} break;}
case 852: case 852:
#line 3738 "parse.y" #line 3732 "parse.y"
{ yyval.ttype = ansi_opname[BIT_IOR_EXPR]; ; { yyval.ttype = ansi_opname[BIT_IOR_EXPR]; ;
break;} break;}
case 853: case 853:
#line 3740 "parse.y" #line 3734 "parse.y"
{ yyval.ttype = ansi_opname[BIT_XOR_EXPR]; ; { yyval.ttype = ansi_opname[BIT_XOR_EXPR]; ;
break;} break;}
case 854: case 854:
#line 3742 "parse.y" #line 3736 "parse.y"
{ yyval.ttype = ansi_opname[BIT_NOT_EXPR]; ; { yyval.ttype = ansi_opname[BIT_NOT_EXPR]; ;
break;} break;}
case 855: case 855:
#line 3744 "parse.y" #line 3738 "parse.y"
{ yyval.ttype = ansi_opname[COMPOUND_EXPR]; ; { yyval.ttype = ansi_opname[COMPOUND_EXPR]; ;
break;} break;}
case 856: case 856:
#line 3746 "parse.y" #line 3740 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ; { yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;} break;}
case 857: case 857:
#line 3748 "parse.y" #line 3742 "parse.y"
{ yyval.ttype = ansi_opname[LT_EXPR]; ; { yyval.ttype = ansi_opname[LT_EXPR]; ;
break;} break;}
case 858: case 858:
#line 3750 "parse.y" #line 3744 "parse.y"
{ yyval.ttype = ansi_opname[GT_EXPR]; ; { yyval.ttype = ansi_opname[GT_EXPR]; ;
break;} break;}
case 859: case 859:
#line 3752 "parse.y" #line 3746 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ; { yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;} break;}
case 860: case 860:
#line 3754 "parse.y" #line 3748 "parse.y"
{ yyval.ttype = ansi_assopname[yyvsp[0].code]; ; { yyval.ttype = ansi_assopname[yyvsp[0].code]; ;
break;} break;}
case 861: case 861:
#line 3756 "parse.y" #line 3750 "parse.y"
{ yyval.ttype = ansi_opname [MODIFY_EXPR]; ; { yyval.ttype = ansi_opname [MODIFY_EXPR]; ;
break;} break;}
case 862: case 862:
#line 3758 "parse.y" #line 3752 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ; { yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;} break;}
case 863: case 863:
#line 3760 "parse.y" #line 3754 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ; { yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;} break;}
case 864: case 864:
#line 3762 "parse.y" #line 3756 "parse.y"
{ yyval.ttype = ansi_opname[POSTINCREMENT_EXPR]; ; { yyval.ttype = ansi_opname[POSTINCREMENT_EXPR]; ;
break;} break;}
case 865: case 865:
#line 3764 "parse.y" #line 3758 "parse.y"
{ yyval.ttype = ansi_opname[PREDECREMENT_EXPR]; ; { yyval.ttype = ansi_opname[PREDECREMENT_EXPR]; ;
break;} break;}
case 866: case 866:
#line 3766 "parse.y" #line 3760 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ANDIF_EXPR]; ; { yyval.ttype = ansi_opname[TRUTH_ANDIF_EXPR]; ;
break;} break;}
case 867: case 867:
#line 3768 "parse.y" #line 3762 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ORIF_EXPR]; ; { yyval.ttype = ansi_opname[TRUTH_ORIF_EXPR]; ;
break;} break;}
case 868: case 868:
#line 3770 "parse.y" #line 3764 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_NOT_EXPR]; ; { yyval.ttype = ansi_opname[TRUTH_NOT_EXPR]; ;
break;} break;}
case 869: case 869:
#line 3772 "parse.y" #line 3766 "parse.y"
{ yyval.ttype = ansi_opname[COND_EXPR]; ; { yyval.ttype = ansi_opname[COND_EXPR]; ;
break;} break;}
case 870: case 870:
#line 3774 "parse.y" #line 3768 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ; { yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;} break;}
case 871: case 871:
#line 3776 "parse.y" #line 3770 "parse.y"
{ yyval.ttype = ansi_opname[COMPONENT_REF]; ; { yyval.ttype = ansi_opname[COMPONENT_REF]; ;
break;} break;}
case 872: case 872:
#line 3778 "parse.y" #line 3772 "parse.y"
{ yyval.ttype = ansi_opname[MEMBER_REF]; ; { yyval.ttype = ansi_opname[MEMBER_REF]; ;
break;} break;}
case 873: case 873:
#line 3780 "parse.y" #line 3774 "parse.y"
{ yyval.ttype = ansi_opname[CALL_EXPR]; ; { yyval.ttype = ansi_opname[CALL_EXPR]; ;
break;} break;}
case 874: case 874:
#line 3782 "parse.y" #line 3776 "parse.y"
{ yyval.ttype = ansi_opname[ARRAY_REF]; ; { yyval.ttype = ansi_opname[ARRAY_REF]; ;
break;} break;}
case 875: case 875:
#line 3784 "parse.y" #line 3778 "parse.y"
{ yyval.ttype = ansi_opname[NEW_EXPR]; ; { yyval.ttype = ansi_opname[NEW_EXPR]; ;
break;} break;}
case 876: case 876:
#line 3786 "parse.y" #line 3780 "parse.y"
{ yyval.ttype = ansi_opname[DELETE_EXPR]; ; { yyval.ttype = ansi_opname[DELETE_EXPR]; ;
break;} break;}
case 877: case 877:
#line 3788 "parse.y" #line 3782 "parse.y"
{ yyval.ttype = ansi_opname[VEC_NEW_EXPR]; ; { yyval.ttype = ansi_opname[VEC_NEW_EXPR]; ;
break;} break;}
case 878: case 878:
#line 3790 "parse.y" #line 3784 "parse.y"
{ yyval.ttype = ansi_opname[VEC_DELETE_EXPR]; ; { yyval.ttype = ansi_opname[VEC_DELETE_EXPR]; ;
break;} break;}
case 879: case 879:
#line 3793 "parse.y" #line 3787 "parse.y"
{ yyval.ttype = grokoptypename (yyvsp[-1].ftype.t, yyvsp[0].ttype); ; { yyval.ttype = grokoptypename (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;} break;}
case 880: case 880:
#line 3795 "parse.y" #line 3789 "parse.y"
{ yyval.ttype = ansi_opname[ERROR_MARK]; ; { yyval.ttype = ansi_opname[ERROR_MARK]; ;
break;} break;}
} }
...@@ -8390,7 +8384,7 @@ yyerrhandle: ...@@ -8390,7 +8384,7 @@ yyerrhandle:
yystate = yyn; yystate = yyn;
goto yynewstate; goto yynewstate;
} }
#line 3798 "parse.y" #line 3792 "parse.y"
#ifdef SPEW_DEBUG #ifdef SPEW_DEBUG
......
...@@ -3384,18 +3384,12 @@ simple_stmt: ...@@ -3384,18 +3384,12 @@ simple_stmt:
function_try_block: function_try_block:
TRY TRY
{ { $<ttype>$ = begin_function_try_block (); }
if (! current_function_parms_stored)
store_parm_decls ();
expand_start_early_try_stmts ();
}
ctor_initializer_opt compstmt ctor_initializer_opt compstmt
{ { finish_function_try_block ($<ttype>2); }
expand_start_all_catch ();
}
handler_seq handler_seq
{ {
expand_end_all_catch (); finish_function_handler_sequence ($<ttype>2);
$$ = $3; $$ = $3;
} }
; ;
......
...@@ -9503,10 +9503,18 @@ instantiate_decl (d) ...@@ -9503,10 +9503,18 @@ instantiate_decl (d)
else if (TREE_CODE (d) == FUNCTION_DECL) else if (TREE_CODE (d) == FUNCTION_DECL)
{ {
tree t = DECL_SAVED_TREE (code_pattern); tree t = DECL_SAVED_TREE (code_pattern);
tree try_block = NULL_TREE;
start_function (NULL_TREE, d, NULL_TREE, 1); start_function (NULL_TREE, d, NULL_TREE, 1);
store_parm_decls (); store_parm_decls ();
if (t && TREE_CODE (t) == TRY_BLOCK)
{
try_block = t;
begin_function_try_block ();
t = TRY_STMTS (try_block);
}
if (t && TREE_CODE (t) == RETURN_INIT) if (t && TREE_CODE (t) == RETURN_INIT)
{ {
store_return_init store_return_init
...@@ -9533,6 +9541,17 @@ instantiate_decl (d) ...@@ -9533,6 +9541,17 @@ instantiate_decl (d)
my_friendly_assert (TREE_CODE (t) == COMPOUND_STMT, 42); my_friendly_assert (TREE_CODE (t) == COMPOUND_STMT, 42);
tsubst_expr (t, args, /*complain=*/1, tmpl); tsubst_expr (t, args, /*complain=*/1, tmpl);
if (try_block)
{
finish_function_try_block (NULL_TREE);
{
tree handler = TRY_HANDLERS (try_block);
for (; handler; handler = TREE_CHAIN (handler))
tsubst_expr (handler, args, /*complain=*/1, tmpl);
}
finish_function_handler_sequence (NULL_TREE);
}
finish_function (lineno, 0, nested); finish_function (lineno, 0, nested);
} }
......
...@@ -586,6 +586,27 @@ begin_try_block () ...@@ -586,6 +586,27 @@ begin_try_block ()
} }
} }
/* Likewise, for a function-try-block. */
tree
begin_function_try_block ()
{
if (processing_template_decl)
{
tree r = build_min_nt (TRY_BLOCK, NULL_TREE,
NULL_TREE);
add_tree (r);
return r;
}
else
{
if (! current_function_parms_stored)
store_parm_decls ();
expand_start_early_try_stmts ();
return NULL_TREE;
}
}
/* Finish a try-block, which may be given by TRY_BLOCK. */ /* Finish a try-block, which may be given by TRY_BLOCK. */
void void
...@@ -600,6 +621,22 @@ finish_try_block (try_block) ...@@ -600,6 +621,22 @@ finish_try_block (try_block)
} }
} }
/* Likewise, for a function-try-block. */
void
finish_function_try_block (try_block)
tree try_block;
{
if (processing_template_decl)
RECHAIN_STMTS_FROM_LAST (try_block, TRY_STMTS (try_block));
else
{
end_protect_partials ();
expand_start_all_catch ();
in_function_try_handler = 1;
}
}
/* Finish a handler-sequence for a try-block, which may be given by /* Finish a handler-sequence for a try-block, which may be given by
TRY_BLOCK. */ TRY_BLOCK. */
...@@ -615,6 +652,21 @@ finish_handler_sequence (try_block) ...@@ -615,6 +652,21 @@ finish_handler_sequence (try_block)
} }
} }
/* Likewise, for a function-try-block. */
void
finish_function_handler_sequence (try_block)
tree try_block;
{
if (processing_template_decl)
RECHAIN_STMTS_FROM_CHAIN (try_block, TRY_HANDLERS (try_block));
else
{
in_function_try_handler = 0;
expand_end_all_catch ();
}
}
/* Begin a handler. Returns a HANDLER if appropriate. */ /* Begin a handler. Returns a HANDLER if appropriate. */
tree tree
......
...@@ -6858,6 +6858,14 @@ c_expand_return (retval) ...@@ -6858,6 +6858,14 @@ c_expand_return (retval)
expand_goto (dtor_label); expand_goto (dtor_label);
return; return;
} }
else if (in_function_try_handler
&& DECL_CONSTRUCTOR_P (current_function_decl))
{
/* If a return statement appears in a handler of the
function-try-block of a constructor, the program is ill-formed. */
error ("cannot return from a handler of a function-try-block of a constructor");
return;
}
/* Only operator new(...) throw(), can return NULL [expr.new/13]. */ /* Only operator new(...) throw(), can return NULL [expr.new/13]. */
if ((DECL_NAME (current_function_decl) == ansi_opname[(int) NEW_EXPR] if ((DECL_NAME (current_function_decl) == ansi_opname[(int) NEW_EXPR]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment