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