This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ia64 eh, part 17
- To: gcc-patches at gcc dot gnu dot org
- Subject: ia64 eh, part 17
- From: Richard Henderson <rth at redhat dot com>
- Date: Wed, 28 Mar 2001 00:27:53 -0800
This is the complete patch mumbled about in
http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00767.html
and approved by Jason.
r~
* decl.c (struct named_label_list): Rename eh_region to
in_try_scope, add in_catch_scope.
(struct binding_level): Rename eh_region to is_try_scope,
add is_catch_scope.
(note_level_for_try): Rename from note_level_for_eh.
(note_level_for_catch): New.
(poplevel): Copy both is_try_scope and is_catch_scope to
the named_label_list struct.
(check_previous_goto_1): Don't check for catch block via
DECL_ARTIFICIAL; use in_try_scope instead.
(check_goto): Likewise.
* cp-tree.h (note_level_for_try, note_level_for_catch): Declare.
* except.c (expand_start_catch_block): Call note_level_for_catch.
* semantics.c (begin_compound_stmt): Update for note_level_for_try.
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.590
diff -c -p -d -r1.590 cp-tree.h
*** cp-tree.h 2001/03/26 08:37:24 1.590
--- cp-tree.h 2001/03/28 08:24:24
*************** extern void maybe_push_cleanup_level PA
*** 3766,3772 ****
extern void begin_scope PARAMS ((scope_kind));
extern void finish_scope PARAMS ((void));
extern void note_level_for_for PARAMS ((void));
! extern void note_level_for_eh PARAMS ((void));
extern void resume_level PARAMS ((struct binding_level *));
extern void delete_block PARAMS ((tree));
extern void insert_block PARAMS ((tree));
--- 3766,3773 ----
extern void begin_scope PARAMS ((scope_kind));
extern void finish_scope PARAMS ((void));
extern void note_level_for_for PARAMS ((void));
! extern void note_level_for_try PARAMS ((void));
! extern void note_level_for_catch PARAMS ((void));
extern void resume_level PARAMS ((struct binding_level *));
extern void delete_block PARAMS ((tree));
extern void insert_block PARAMS ((tree));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.765
diff -c -p -d -r1.765 decl.c
*** decl.c 2001/03/27 02:17:45 1.765
--- decl.c 2001/03/28 08:24:25
*************** struct named_label_list
*** 282,289 ****
tree old_value;
tree label_decl;
tree bad_decls;
- int eh_region;
struct named_label_list *next;
};
#define named_labels cp_function_chain->x_named_labels
--- 282,290 ----
tree old_value;
tree label_decl;
tree bad_decls;
struct named_label_list *next;
+ unsigned int in_try_scope : 1;
+ unsigned int in_catch_scope : 1;
};
#define named_labels cp_function_chain->x_named_labels
*************** struct binding_level
*** 456,468 ****
worry about ambiguous (ARM or ISO) scope rules. */
unsigned is_for_scope : 1;
! /* True if this level corresponds to an EH region, as for a try block.
! Currently this information is only available while building the
! tree structure. */
! unsigned eh_region : 1;
! /* Four bits left for this word. */
#if defined(DEBUG_CP_BINDING_LEVELS)
/* Binding depth at which this level began. */
unsigned binding_depth;
--- 457,472 ----
worry about ambiguous (ARM or ISO) scope rules. */
unsigned is_for_scope : 1;
! /* True if this level corresponds to a TRY block. Currently this
! information is only available while building the tree structure. */
! unsigned is_try_scope : 1;
! /* True if this level corresponds to a CATCH block. Currently this
! information is only available while building the tree structure. */
! unsigned is_catch_scope : 1;
+ /* Three bits left for this word. */
+
#if defined(DEBUG_CP_BINDING_LEVELS)
/* Binding depth at which this level began. */
unsigned binding_depth;
*************** note_level_for_for ()
*** 920,930 ****
/* Record that the current binding level represents a try block. */
void
! note_level_for_eh ()
{
! current_binding_level->eh_region = 1;
}
/* For a binding between a name and an entity at a block scope,
this is the `struct binding_level' for the block. */
#define BINDING_LEVEL(NODE) \
--- 924,942 ----
/* Record that the current binding level represents a try block. */
void
! note_level_for_try ()
{
! current_binding_level->is_try_scope = 1;
}
+ /* Record that the current binding level represents a catch block. */
+
+ void
+ note_level_for_catch ()
+ {
+ current_binding_level->is_catch_scope = 1;
+ }
+
/* For a binding between a name and an entity at a block scope,
this is the `struct binding_level' for the block. */
#define BINDING_LEVEL(NODE) \
*************** poplevel (keep, reverse, functionbody)
*** 1326,1333 ****
if (labels->binding_level == current_binding_level)
{
tree decl;
! if (current_binding_level->eh_region)
! labels->eh_region = 1;
for (decl = labels->names_in_scope; decl;
decl = TREE_CHAIN (decl))
if (decl_jump_unsafe (decl))
--- 1338,1347 ----
if (labels->binding_level == current_binding_level)
{
tree decl;
! if (current_binding_level->is_try_scope)
! labels->in_try_scope = 1;
! if (current_binding_level->is_catch_scope)
! labels->in_catch_scope = 1;
for (decl = labels->names_in_scope; decl;
decl = TREE_CHAIN (decl))
if (decl_jump_unsafe (decl))
*************** check_previous_goto_1 (decl, level, name
*** 4946,4955 ****
identified = 1;
}
! if (problem > 1 && DECL_ARTIFICIAL (new_decls))
! /* Can't skip init of __exception_info. */
! cp_error_at (" enters catch block", new_decls);
! else if (problem > 1)
cp_error_at (" crosses initialization of `%#D'",
new_decls);
else
--- 4960,4966 ----
identified = 1;
}
! if (problem > 1)
cp_error_at (" crosses initialization of `%#D'",
new_decls);
else
*************** check_previous_goto_1 (decl, level, name
*** 4959,4965 ****
if (b == level)
break;
! if (b->eh_region && ! saw_eh)
{
if (! identified)
{
--- 4970,4976 ----
if (b == level)
break;
! if ((b->is_try_scope || b->is_catch_scope) && ! saw_eh)
{
if (! identified)
{
*************** check_previous_goto_1 (decl, level, name
*** 4972,4978 ****
pedwarn_with_file_and_line (file, line, " from here");
identified = 1;
}
! error (" enters try block");
saw_eh = 1;
}
}
--- 4983,4992 ----
pedwarn_with_file_and_line (file, line, " from here");
identified = 1;
}
! if (b->is_try_scope)
! error (" enters try block");
! else
! error (" enters catch block");
saw_eh = 1;
}
}
*************** check_goto (decl)
*** 5051,5057 ****
if (lab == 0)
return;
! if ((lab->eh_region || lab->bad_decls) && !identified)
{
cp_pedwarn_at ("jump to label `%D'", decl);
pedwarn (" from here");
--- 5065,5072 ----
if (lab == 0)
return;
! if ((lab->in_try_scope || lab->in_catch_scope || lab->bad_decls)
! && !identified)
{
cp_pedwarn_at ("jump to label `%D'", decl);
pedwarn (" from here");
*************** check_goto (decl)
*** 5072,5079 ****
cp_pedwarn_at (" enters scope of non-POD `%#D'", b);
}
! if (lab->eh_region)
error (" enters try block");
}
/* Define a label, specifying the location in the source file.
--- 5087,5096 ----
cp_pedwarn_at (" enters scope of non-POD `%#D'", b);
}
! if (lab->in_try_scope)
error (" enters try block");
+ else if (lab->in_catch_scope)
+ error (" enters catch block");
}
/* Define a label, specifying the location in the source file.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/except.c,v
retrieving revision 1.126
diff -c -p -d -r1.126 except.c
*** except.c 2001/03/28 05:24:22 1.126
--- except.c 2001/03/28 08:24:25
*************** expand_start_catch_block (decl)
*** 616,621 ****
--- 616,622 ----
/* 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 || ! decl_is_java_type (TREE_TYPE (decl), 1))
{
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.196
diff -c -p -d -r1.196 semantics.c
*** semantics.c 2001/03/27 02:17:45 1.196
--- semantics.c 2001/03/28 08:24:25
*************** begin_compound_stmt (has_no_scope)
*** 832,838 ****
{
do_pushlevel ();
if (is_try)
! note_level_for_eh ();
}
else
/* Normally, we try hard to keep the BLOCK for a
--- 832,838 ----
{
do_pushlevel ();
if (is_try)
! note_level_for_try ();
}
else
/* Normally, we try hard to keep the BLOCK for a