This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to clean up EH code
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH to clean up EH code
- From: Jason Merrill <jason_merrill at redhat dot com>
- Date: 21 May 2001 16:03:55 +0100
It seemed pointless to me to have both a HANDLER tree code and another
START_CATCH_STMT. In addition to the redundancy problem, it led to
problems with nesting consistency; we were failing to push and pop blocks
and EH regions in LIFO order (though that doesn't currently break
anything). This patch cleans that up and removes a couple of redundant
blocks.
Tested i686-pc-linux-gnu. Applied to trunk only.
2001-05-21 Jason Merrill <jason_merrill@redhat.com>
* cp-tree.def (START_CATCH_STMT): Lose.
* dump.c (cp_dump_tree): Don't dump it. Do dump HANDLER_PARMS.
* tree.c (cp_statement_code_p): Don't case it.
* semantics.c (cp_expand_stmt): Likewise.
* except.c (expand_start_catch_block): Don't start any blocks.
Return the type.
(expand_end_catch_block): Don't end any blocks.
* parse.y (handler): Don't pass anything from finish_handler_parms
to finish_handler.
* pt.c (tsubst_expr): Likewise.
* semantics.c (begin_handler): Call note_level_for_catch here.
(finish_handler_parms): Don't return anything.
(genrtl_catch_block, begin_catch_block): Lose.
(genrtl_handler): Call expand_start_catch here.
*** cp-tree.def.~1~ Tue May 1 21:54:57 2001
--- cp-tree.def Mon May 21 14:42:35 2001
*************** DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e'
*** 229,242 ****
constructed. If, after this point, the CLEANUP_DECL goes out of
scope, the CLEANUP_EXPR must be run. */
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
- /* A START_CATCH_STMT marks the beginning of a catch handler for the
- the START_CATCH_TYPE. If this is CATCH_ALL_TYPE, then the handler
- catches all types. */
- DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
DEFTREECODE (HANDLER, "handler", 'e', 2)
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
--- 229,242 ----
constructed. If, after this point, the CLEANUP_DECL goes out of
scope, the CLEANUP_EXPR must be run. */
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
+ /* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
+ CATCH_ALL_TYPE, then the handler catches all types. The declaration of
+ the catch variable is in HANDLER_PARMS, and the body block in
+ HANDLER_BODY. */
DEFTREECODE (HANDLER, "handler", 'e', 2)
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
*** cp-tree.h.~1~ Sat May 19 00:24:16 2001
--- cp-tree.h Mon May 21 14:40:36 2001
*************** enum ptrmemfunc_vbit_where_t
*** 3065,3072 ****
#define FN_TRY_BLOCK_P(NODE) TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
#define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0)
#define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1)
#define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0)
- #define START_CATCH_TYPE(NODE) TREE_TYPE (START_CATCH_STMT_CHECK (NODE))
/* Nonzero if this CTOR_STMT is for the beginning of a constructor. */
#define CTOR_BEGIN_P(NODE) \
--- 3065,3072 ----
#define FN_TRY_BLOCK_P(NODE) TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
#define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0)
#define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1)
+ #define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE))
#define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0)
/* Nonzero if this CTOR_STMT is for the beginning of a constructor. */
#define CTOR_BEGIN_P(NODE) \
*************** extern cp_printer *cp_printers[256];
*** 4009,4015 ****
/* in except.c */
extern void init_exception_processing PARAMS ((void));
extern tree expand_start_catch_block PARAMS ((tree));
! extern void expand_end_catch_block PARAMS ((tree));
extern void expand_builtin_throw PARAMS ((void));
extern void expand_eh_spec_block PARAMS ((tree));
extern void expand_exception_blocks PARAMS ((void));
--- 4009,4015 ----
/* in except.c */
extern void init_exception_processing PARAMS ((void));
extern tree expand_start_catch_block PARAMS ((tree));
! extern void expand_end_catch_block PARAMS ((void));
extern void expand_builtin_throw PARAMS ((void));
extern void expand_eh_spec_block PARAMS ((tree));
extern void expand_exception_blocks PARAMS ((void));
*************** extern void finish_function_try_block
*** 4275,4283 ****
extern void finish_function_handler_sequence PARAMS ((tree));
extern void finish_cleanup_try_block PARAMS ((tree));
extern tree begin_handler PARAMS ((void));
! extern tree finish_handler_parms PARAMS ((tree, tree));
extern void begin_catch_block PARAMS ((tree));
! extern void finish_handler PARAMS ((tree, tree));
extern void finish_cleanup PARAMS ((tree, tree));
extern tree begin_compound_stmt PARAMS ((int));
extern tree finish_compound_stmt PARAMS ((int, tree));
--- 4275,4283 ----
extern void finish_function_handler_sequence PARAMS ((tree));
extern void finish_cleanup_try_block PARAMS ((tree));
extern tree begin_handler PARAMS ((void));
! extern void finish_handler_parms PARAMS ((tree, tree));
extern void begin_catch_block PARAMS ((tree));
! extern void finish_handler PARAMS ((tree));
extern void finish_cleanup PARAMS ((tree, tree));
extern tree begin_compound_stmt PARAMS ((int));
extern tree finish_compound_stmt PARAMS ((int, tree));
*** decl.c.~1~ Sat May 19 00:24:17 2001
--- decl.c Sat May 19 00:22:37 2001
*************** grokdeclarator (declarator, declspecs, d
*** 10064,10072 ****
explicit_int = -1;
! /* We handle `main' specially here, because 'main () { }' is so
! common. With no options, it is allowed. With -Wreturn-type,
! it is a warning. It is only an error with -pedantic-errors. */
is_main = (funcdef_flag
&& MAIN_NAME_P (dname)
&& ctype == NULL_TREE
--- 10064,10072 ----
explicit_int = -1;
! /* We handle `main' specially here, because 'main () { }' is so
! common. With no options, it is allowed. With -Wreturn-type,
! it is a warning. It is only an error with -pedantic-errors. */
is_main = (funcdef_flag
&& MAIN_NAME_P (dname)
&& ctype == NULL_TREE
*** dump.c.~1~ Fri May 18 10:18:58 2001
--- dump.c Mon May 21 14:53:01 2001
*************** cp_dump_tree (di, t)
*** 230,235 ****
--- 230,236 ----
case HANDLER:
dump_stmt (di, t);
+ dump_child ("parm", HANDLER_PARMS (t));
dump_child ("body", HANDLER_BODY (t));
dump_next_stmt (di, t);
break;
*************** cp_dump_tree (di, t)
*** 243,254 ****
case SUBOBJECT:
dump_stmt (di, t);
dump_child ("clnp", TREE_OPERAND (t, 0));
- dump_next_stmt (di, t);
- break;
-
- case START_CATCH_STMT:
- dump_stmt (di, t);
- queue_and_dump_type (di, t);
dump_next_stmt (di, t);
break;
--- 244,249 ----
*** except.c.~1~ Sat May 19 00:24:17 2001
--- except.c Mon May 21 14:05:47 2001
*************** tree
*** 391,398 ****
expand_start_catch_block (decl)
tree decl;
{
- tree compound_stmt_1;
- tree compound_stmt_2;
tree exp = NULL_TREE;
tree type;
bool is_java;
--- 391,396 ----
*************** expand_start_catch_block (decl)
*** 404,419 ****
if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
decl = NULL_TREE;
- /* Create a binding level for the eh_info and the exception object
- cleanup. */
- compound_stmt_1 = begin_compound_stmt (/*has_no_scope=*/0);
- note_level_for_catch ();
-
if (decl)
type = prepare_eh_type (TREE_TYPE (decl));
else
type = NULL_TREE;
- begin_catch_block (type);
is_java = false;
if (decl)
--- 402,411 ----
*************** expand_start_catch_block (decl)
*** 452,464 ****
if (! is_java)
push_eh_cleanup (type);
- /* Create a binding level for the parm. */
- compound_stmt_2 = begin_compound_stmt (/*has_no_scope=*/0);
-
if (decl)
initialize_handler_parm (decl, exp);
! return build_tree_list (compound_stmt_1, compound_stmt_2);
}
--- 444,453 ----
if (! is_java)
push_eh_cleanup (type);
if (decl)
initialize_handler_parm (decl, exp);
! return type;
}
*************** expand_start_catch_block (decl)
*** 467,478 ****
the label to jump to if this catch block didn't match. */
void
! expand_end_catch_block (blocks)
! tree blocks;
{
- tree compound_stmt_1 = blocks ? TREE_PURPOSE (blocks): NULL_TREE;
- tree compound_stmt_2 = blocks ? TREE_VALUE (blocks): NULL_TREE;
-
if (! doing_eh (1))
return;
--- 456,463 ----
the label to jump to if this catch block didn't match. */
void
! expand_end_catch_block ()
{
if (! doing_eh (1))
return;
*************** expand_end_catch_block (blocks)
*** 482,492 ****
&& (DECL_CONSTRUCTOR_P (current_function_decl)
|| DECL_DESTRUCTOR_P (current_function_decl)))
finish_expr_stmt (build_throw (NULL_TREE));
-
- /* Cleanup the EH parameter. */
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_2);
- /* Cleanup the EH object. */
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_1);
}
tree
--- 467,472 ----
*** parse.y.~1~ Sat May 19 00:24:17 2001
--- parse.y Fri May 18 20:00:26 2001
*************** handler_seq:
*** 3518,3528 ****
handler:
CATCH
! { $<ttype>$ = begin_handler(); }
handler_args
! { $<ttype>$ = finish_handler_parms ($3, $<ttype>2); }
compstmt
! { finish_handler ($<ttype>4, $<ttype>2); }
;
type_specifier_seq:
--- 3518,3528 ----
handler:
CATCH
! { $<ttype>$ = begin_handler (); }
handler_args
! { finish_handler_parms ($3, $<ttype>2); }
compstmt
! { finish_handler ($<ttype>2); }
;
type_specifier_seq:
*** pt.c.~1~ Sat May 19 00:24:17 2001
--- pt.c Sat May 19 00:07:16 2001
*************** tsubst_expr (t, args, complain, in_decl)
*** 7445,7451 ****
case HANDLER:
{
tree decl;
- tree blocks;
prep_stmt (t);
stmt = begin_handler ();
--- 7445,7450 ----
*************** tsubst_expr (t, args, complain, in_decl)
*** 7460,7468 ****
}
else
decl = NULL_TREE;
! blocks = finish_handler_parms (decl, stmt);
tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
! finish_handler (blocks, stmt);
}
break;
--- 7459,7467 ----
}
else
decl = NULL_TREE;
! finish_handler_parms (decl, stmt);
tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
! finish_handler (stmt);
}
break;
*** semantics.c.~1~ Sat May 19 00:24:17 2001
--- semantics.c Mon May 21 14:40:05 2001
*************** static void emit_associated_thunks PARAM
*** 54,60 ****
static void genrtl_try_block PARAMS ((tree));
static void genrtl_eh_spec_block PARAMS ((tree));
static void genrtl_handler PARAMS ((tree));
- static void genrtl_catch_block PARAMS ((tree));
static void genrtl_ctor_stmt PARAMS ((tree));
static void genrtl_subobject PARAMS ((tree));
static void genrtl_named_return_value PARAMS ((void));
--- 54,59 ----
*************** genrtl_handler (t)
*** 721,726 ****
--- 720,727 ----
tree t;
{
genrtl_do_pushlevel ();
+ if (!processing_template_decl)
+ expand_start_catch (HANDLER_TYPE (t));
expand_stmt (HANDLER_BODY (t));
if (!processing_template_decl)
expand_end_catch ();
*************** begin_handler ()
*** 734,740 ****
--- 735,744 ----
tree r;
r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
add_stmt (r);
+ /* Create a binding level for the eh_info and the exception object
+ cleanup. */
do_pushlevel ();
+ note_level_for_catch ();
return r;
}
*************** begin_handler ()
*** 742,754 ****
HANDLER. DECL is the declaration for the catch parameter, or NULL
if this is a `catch (...)' clause. */
! tree
finish_handler_parms (decl, handler)
tree decl;
tree handler;
{
! tree blocks = NULL_TREE;
!
if (processing_template_decl)
{
if (decl)
--- 746,757 ----
HANDLER. DECL is the declaration for the catch parameter, or NULL
if this is a `catch (...)' clause. */
! void
finish_handler_parms (decl, handler)
tree decl;
tree handler;
{
! tree type = NULL_TREE;
if (processing_template_decl)
{
if (decl)
*************** finish_handler_parms (decl, handler)
*** 757,803 ****
decl = push_template_decl (decl);
add_decl_stmt (decl);
RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
}
}
else
! blocks = expand_start_catch_block (decl);
!
! if (decl)
! TREE_TYPE (handler) = TREE_TYPE (decl);
!
! return blocks;
! }
!
! /* Generate the RTL for a START_CATCH_STMT. */
! static void
! genrtl_catch_block (type)
! tree type;
! {
! expand_start_catch (type);
! }
!
! /* Note the beginning of a handler for TYPE. This function is called
! at the point to which control should be transferred when an
! appropriately-typed exception is thrown. */
!
! void
! begin_catch_block (type)
! tree type;
! {
! add_stmt (build (START_CATCH_STMT, type));
}
/* Finish a handler, which may be given by HANDLER. The BLOCKs are
the return value from the matching call to finish_handler_parms. */
void
! finish_handler (blocks, handler)
! tree blocks;
tree handler;
{
if (!processing_template_decl)
! expand_end_catch_block (blocks);
do_poplevel ();
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}
--- 760,783 ----
decl = push_template_decl (decl);
add_decl_stmt (decl);
RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
+ type = TREE_TYPE (decl);
}
}
else
! type = expand_start_catch_block (decl);
! HANDLER_TYPE (handler) = type;
}
/* Finish a handler, which may be given by HANDLER. The BLOCKs are
the return value from the matching call to finish_handler_parms. */
void
! finish_handler (handler)
tree handler;
{
if (!processing_template_decl)
! expand_end_catch_block ();
do_poplevel ();
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}
*************** cp_expand_stmt (t)
*** 2165,2174 ****
{
case CLEANUP_STMT:
genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
- break;
-
- case START_CATCH_STMT:
- genrtl_catch_block (TREE_TYPE (t));
break;
case CTOR_STMT:
--- 2145,2150 ----
*** tree.c.~1~ Fri May 18 10:18:59 2001
--- tree.c Mon May 21 14:51:10 2001
*************** cp_statement_code_p (code)
*** 1031,1037 ****
{
case SUBOBJECT:
case CLEANUP_STMT:
- case START_CATCH_STMT:
case CTOR_STMT:
case CTOR_INITIALIZER:
case RETURN_INIT:
--- 1031,1036 ----