OSDN Git Service

* semantics.c (begin_function_try_block, finish_function_try_block,
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Aug 1999 10:45:00 +0000 (10:45 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Aug 1999 10:45:00 +0000 (10:45 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28624 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/parse.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c

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