C++ PATCH: rethrow from cdtor function try block
Nathan Sidwell
nathan@acm.org
Tue May 4 09:19:00 GMT 1999
Hi,
here's a patch to fix the defect reported as
http://egcs.cygnus.com/ml/egcs-bugs/1999-04/msg00512.html . The patch implements
15.3/16.
I keep a static local variable in parse.y, which is 1 inside a cdtor's
function-try-block catcher. Outside it is zero, and inside a nested try block
it is greater than 1. At the end of a handler, I emit a rethrow, if this flag
is 1. This logic will fail, if there is a local class inside a cdtor's
function-try-block catcher which contains member functions with try blocks. I
find it hard to imagine why such a situation would be useful.
I've removed some cruft from cp-tree.h (a now obsolete global variable
declaration).
Attached is a test case which checks this patch works.
Enjoy, ok to install?
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
You can up the bandwidth, but you can't up the speed of light
nathan@acm.org http://www.cs.bris.ac.uk/~nathan/ nathan@cs.bris.ac.uk
1999-05-04 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (exception_throw_decl): Remove obsolete global.
* parse.y (cdtor_function_try_block): New static variable.
(function_try_block): Set it for cdtor's. Clear it afterwards.
(try_block): Nest it, if needed.
(handler): Emit trailing rethrow, if needed.
Index: egcs/gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/egcs/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.229
diff -c -3 -p -r1.229 cp-tree.h
*** cp-tree.h 1999/05/02 17:45:13 1.229
--- cp-tree.h 1999/05/04 15:55:05
*************** extern int pedantic;
*** 325,334 ****
#define C_SET_EXP_ORIGINAL_CODE(exp, code) \
(TREE_COMPLEXITY (exp) = (int)(code))
- /* If non-zero, a VAR_DECL whose cleanup will cause a throw to the
- next exception handler. */
- extern tree exception_throw_decl;
-
extern tree double_type_node, long_double_type_node, float_type_node;
extern tree char_type_node, unsigned_char_type_node, signed_char_type_node;
extern tree ptrdiff_type_node;
--- 325,330 ----
Index: egcs/gcc/cp/parse.y
===================================================================
RCS file: /cvs/egcs/egcs/gcc/cp/parse.y,v
retrieving revision 1.119
diff -c -3 -p -r1.119 parse.y
*** parse.y 1999/04/22 17:36:48 1.119
--- parse.y 1999/05/04 15:55:07
*************** static int parse_decl PROTO((tree, tree,
*** 69,74 ****
--- 69,77 ----
int have_extern_spec;
int used_extern_spec;
+ /* 1 iff we're in a catcher of a cdtor function try block. */
+ static int cdtor_function_try_block;
+
/* Cons up an empty parameter list. */
#ifdef __GNUC__
__inline
*************** base_init:
*** 801,807 ****
}
else if (current_class_type == NULL_TREE)
error ("base initializers not allowed for non-member functions");
! else if (! DECL_CONSTRUCTOR_P (current_function_decl))
error ("only constructors take base initializers");
}
;
--- 804,810 ----
}
else if (current_class_type == NULL_TREE)
error ("base initializers not allowed for non-member functions");
! else
error ("only constructors take base initializers");
}
;
*************** function_try_block:
*** 3390,3398 ****
--- 3393,3405 ----
ctor_initializer_opt compstmt
{
expand_start_all_catch ();
+ if (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))
+ cdtor_function_try_block = 1;
}
handler_seq
{
+ cdtor_function_try_block = 0;
expand_end_all_catch ();
$$ = $3;
}
*************** try_block:
*** 3402,3410 ****
TRY
{ $<ttype>$ = begin_try_block (); }
compstmt
! { finish_try_block ($<ttype>2); }
handler_seq
! { finish_handler_sequence ($<ttype>2); }
;
handler_seq:
--- 3409,3425 ----
TRY
{ $<ttype>$ = begin_try_block (); }
compstmt
! {
! finish_try_block ($<ttype>2);
! if (cdtor_function_try_block)
! cdtor_function_try_block++;
! }
handler_seq
! {
! if (cdtor_function_try_block)
! cdtor_function_try_block--;
! finish_handler_sequence ($<ttype>2);
! }
;
handler_seq:
*************** handler:
*** 3418,3424 ****
handler_args
{ finish_handler_parms ($<ttype>2); }
compstmt
! { finish_handler ($<ttype>2); }
;
type_specifier_seq:
--- 3433,3445 ----
handler_args
{ finish_handler_parms ($<ttype>2); }
compstmt
! {
! if (cdtor_function_try_block == 1)
! /* A cdtor function try block rethrows [except.handle/16]. */
! expand_throw (NULL_TREE);
!
! finish_handler ($<ttype>2);
! }
;
type_specifier_seq:
More information about the Gcc-patches
mailing list