public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [basic-improvements] try/finally support for c/c++
@ 2002-11-05 15:16 Aldy Hernandez
  2002-11-05 15:57 ` Richard Henderson
                   ` (2 more replies)
  0 siblings, 3 replies; 128+ messages in thread
From: Aldy Hernandez @ 2002-11-05 15:16 UTC (permalink / raw)
  To: rth, gcc-patches, jakub; +Cc: jason

As promised.  Here are the try/finally patches for C and C++.

As can be seen by the ChangeLog, the C++ bits were kindly supplied by
Jason Merrill (thank-you beers still pending).

Jakub has some tests for try/finally mixing C and C++ exceptions.
He'll be posting those later, right? :)

In a nutshell, try/finally is the coolest thing since sliced bread.
Now you can do stuff like:

    __try {
       blah;
       blah;
       return;
    }
    __finally {
       /* guaranteed to run before the return */
    }

Even cooler would be code in the kernel:

     __try {
       clear_interrupts();
       stuff;
       stuff;
     }
     __finally {
       set_interrupts();
     }

That way you'll never forget to turn on interrupts again :).  Well...

You can even have C call C++, C++ throw an exception, and the finally
clause in C execute as the stack unwinds up to the caller.

     C_function() {
        __try {
	   C++_function_that_throws_exception();
	}
	__finally {
           /* guaranteed to be executed as the stack unwinds up to
	      C_function's caller  */
	}
     }

Bootstrapped on x86 (c, c++, java, fortran).  Regtest almost done.

Ok?

2002-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* Makefile.in (LIB2ADDEH): Add unwind-c.c.
	(c-semantics.o): Depend on libfuncs.h and except.h.

	* config/t-linux (LIB2ADDEH): Same.

	* config/ia64/t-ia64 (LIB2ADDEH): Add unwind-c.c.

	* testsuite/gcc.c-torture/execute/try-finally-1.c: New.

	* testsuite/gcc.c-torture/execute/try-finally-2.c: New.

	* c-decl.c (c_init_decl_processing): Set eh_personality_libfunc.
	Use EH for cleanups.
	Include libfuncs.h, except.h.

	* unwind-c.c: New file.

	* c-common.def (TRY_FINALLY_STMT): New.

	* c-semantics.c (expand_stmt): Add TRY_FINALLY_STMT case.
	(genrtl_try_finally_stmt): New.

	* c-tree.h: Add prototype to build_try_finally_stmt.

	* c-typeck.c (build_try_finally_stmt): New.

	* c-common.c (statement_code_p): Add case for TRY_FINALLY_STMT.

	* c-common.h (enum rid): Add RID_FINALLY.
	Add prototype for genrtl_try_finally_stmt.
	(TRY_FINALLY_TRY): New.
	(TRY_FINALLY_FINALLY): New.

	* c-parse.in: Add FINALLY tokens.
	(reswords): Add __try and __finally.
	(rid_to_yy): Add RID_FINALLY.  Enable RID_TRY.
	(stmt): Add try/finally grammar case.
	(try_finally_begin): New production.

	* cp/lex.c (reswords): Add __finally, __try tokens.
	(rid_to_yy): Add FINALLY.

	* doc/extend.texi: Add documentation for try/finally.

2002-11-05  Jason Merrill  <jason@redhat.com>

	* cp/cp-tree.h: Add prototypes for finish_try_finally_try and
	finish_try_finally_finally.

	* cp/parse.y: Add FINALLY token.
	Add handler_seq and finally_stmt productions.
	Modify try_block to handle try/finally.

	* cp/pt.c (tsubst_expr): Add case for TRY_FINALLY_STMT.

	* cp/semantics.c (genrtl_try_block): Handle try/finally.
	(begin_try_finally): New.
	(finish_try_finally_try): New.
	(finish_try_finally_finally): New.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.939.2.10
diff -c -p -r1.939.2.10 Makefile.in
*** Makefile.in	21 Oct 2002 17:51:50 -0000	1.939.2.10
--- Makefile.in	5 Nov 2002 23:01:34 -0000
*************** CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(IN
*** 399,405 ****
  
  # Additional sources to handle exceptions; overridden by targets as needed.
  LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
!   $(srcdir)/unwind-sjlj.c
  LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
  
  # nm flags to list global symbols in libgcc object files.
--- 399,405 ----
  
  # Additional sources to handle exceptions; overridden by targets as needed.
  LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
!   $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
  LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
  
  # nm flags to list global symbols in libgcc object files.
*************** c-format.o : c-format.c $(CONFIG_H) $(SY
*** 1252,1257 ****
--- 1252,1258 ----
  
  c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
  	flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
+ 	libfuncs.h except.h \
  	$(EXPR_H) $(PREDICT_H)
  
  c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) tree-dump.h
Index: unwind-c.c
===================================================================
RCS file: unwind-c.c
diff -N unwind-c.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- unwind-c.c	5 Nov 2002 23:01:38 -0000
***************
*** 0 ****
--- 1,185 ----
+ /* Supporting functions for C exception handling.
+ 
+    Copyright (C) 2002 Free Software Foundation, Inc.
+    Contributed by Aldy Hernandez <aldy@quesejoda.com>.
+    Shamelessly stolen from the Java front end.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ #include "tconfig.h"
+ #include "tsystem.h"
+ #include "unwind.h"
+ #include "unwind-pe.h"
+ 
+ typedef struct
+ {
+   _Unwind_Ptr Start;
+   _Unwind_Ptr LPStart;
+   _Unwind_Ptr ttype_base;
+   const unsigned char *TType;
+   const unsigned char *action_table;
+   unsigned char ttype_encoding;
+   unsigned char call_site_encoding;
+ } lsda_header_info;
+ 
+ static const unsigned char *
+ parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
+                    lsda_header_info *info)
+ {
+   _Unwind_Word tmp;
+   unsigned char lpstart_encoding;
+ 
+   info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
+ 
+   /* Find @LPStart, the base to which landing pad offsets are relative.  */
+   lpstart_encoding = *p++;
+   if (lpstart_encoding != DW_EH_PE_omit)
+     p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
+   else
+     info->LPStart = info->Start;
+ 
+   /* Find @TType, the base of the handler and exception spec type data.  */
+   info->ttype_encoding = *p++;
+   if (info->ttype_encoding != DW_EH_PE_omit)
+     {
+       p = read_uleb128 (p, &tmp);
+       info->TType = p + tmp;
+     }
+   else
+     info->TType = 0;
+ 
+   /* The encoding and length of the call-site table; the action table
+      immediately follows.  */
+   info->call_site_encoding = *p++;
+   p = read_uleb128 (p, &tmp);
+   info->action_table = p + tmp;
+ 
+   return p;
+ }
+ 
+ #ifdef __USING_SJLJ_EXCEPTIONS__
+ #define PERSONALITY_FUNCTION    __gcc_personality_sj0
+ #define __builtin_eh_return_data_regno(x) x
+ #else
+ #define PERSONALITY_FUNCTION    __gcc_personality_v0
+ #endif
+ #define PERSONALITY_FUNCTION    __gcc_personality_v0
+ 
+ _Unwind_Reason_Code
+ PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
+                       struct _Unwind_Exception *, struct _Unwind_Context *);
+ 
+ _Unwind_Reason_Code
+ PERSONALITY_FUNCTION (int version,
+                       _Unwind_Action actions,
+                       _Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED,
+                       struct _Unwind_Exception *ue_header,
+                       struct _Unwind_Context *context)
+ {
+   lsda_header_info info;
+   const unsigned char *language_specific_data, *p, *action_record;
+   _Unwind_Ptr landing_pad, ip;
+ 
+   if (version != 1)
+     return _URC_FATAL_PHASE1_ERROR;
+ 
+   /* Currently we only support cleanups for C.  */
+   if (actions != _UA_CLEANUP_PHASE)
+     return _URC_CONTINUE_UNWIND;
+ 
+   language_specific_data = (const unsigned char *)
+     _Unwind_GetLanguageSpecificData (context);
+ 
+   /* If no LSDA, then there are no handlers or cleanups.  */
+   if (! language_specific_data)
+     return _URC_CONTINUE_UNWIND;
+ 
+   /* Parse the LSDA header.  */
+   p = parse_lsda_header (context, language_specific_data, &info);
+   ip = _Unwind_GetIP (context) - 1;
+   landing_pad = 0;
+ 
+ #ifdef __USING_SJLJ_EXCEPTIONS__
+   /* The given "IP" is an index into the call-site table, with two
+      exceptions -- -1 means no-action, and 0 means terminate.  But
+      since we're using uleb128 values, we've not got random access
+      to the array.  */
+   if ((int) ip <= 0)
+     return _URC_CONTINUE_UNWIND;
+   else
+     {
+       _Unwind_Word cs_lp, cs_action;
+       do
+         {
+           p = read_uleb128 (p, &cs_lp);
+           p = read_uleb128 (p, &cs_action);
+         }
+       while (--ip);
+ 
+       /* Can never have null landing pad for sjlj -- that would have
+ 	 been indicated by a -1 call site index.  */
+       landing_pad = cs_lp + 1;
+       if (cs_action)
+         action_record = info.action_table + cs_action - 1;
+       goto found_something;
+     }
+ #else
+   /* Search the call-site table for the action associated with this IP.  */
+   while (p < info.action_table)
+     {
+       _Unwind_Ptr cs_start, cs_len, cs_lp;
+       _Unwind_Word cs_action;
+ 
+       /* Note that all call-site encodings are "absolute" displacements.  */
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
+       p = read_uleb128 (p, &cs_action);
+ 
+       /* The table is sorted, so if we've passed the ip, stop.  */
+       if (ip < info.Start + cs_start)
+         p = info.action_table;
+       else if (ip < info.Start + cs_start + cs_len)
+         {
+           if (cs_lp)
+             landing_pad = info.LPStart + cs_lp;
+           if (cs_action)
+             action_record = info.action_table + cs_action - 1;
+           goto found_something;
+         }
+     }
+   
+ #endif
+ 
+   /* Blahhh.  IP is not in table.  Run away.  */
+   return _URC_CONTINUE_UNWIND;
+ 
+  found_something:
+   if (landing_pad == 0)
+     {
+       /* IP is present, but has a null landing pad.  No handler to be
+ 	 run.  */
+       return _URC_CONTINUE_UNWIND;
+     }
+ 
+   _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
+                  (_Unwind_Ptr) ue_header);
+   _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0);
+   _Unwind_SetIP (context, landing_pad);
+   return _URC_INSTALL_CONTEXT;
+ }
Index: c-common.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.def,v
retrieving revision 1.11.8.2
diff -c -p -r1.11.8.2 c-common.def
*** c-common.def	1 Oct 2002 17:31:37 -0000	1.11.8.2
--- c-common.def	5 Nov 2002 23:01:39 -0000
*************** DEFTREECODE (SCOPE_STMT, "scope_stmt", '
*** 96,101 ****
--- 96,105 ----
     other semantics.  FILE_STMT_FILENAME gives the name.  */
  DEFTREECODE (FILE_STMT, "file_stmt", 'e', 1)
  
+ /* Describe a try/finally construct.  TRY_FINALLY_TRY gives the try
+    block.  TRY_FINALLY_FINALLY gives the finally block.  */
+ DEFTREECODE (TRY_FINALLY_STMT, "try_finally_stmt", 'e', 2)
+ 
  /* Used to represent a CASE_LABEL. The operands are CASE_LOW and
     CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
     'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.44.4.4
diff -c -p -r1.44.4.4 c-semantics.c
*** c-semantics.c	1 Oct 2002 17:31:38 -0000	1.44.4.4
--- c-semantics.c	5 Nov 2002 23:01:39 -0000
*************** Software Foundation, 59 Temple Place - S
*** 37,42 ****
--- 37,44 ----
  #include "output.h"
  #include "timevar.h"
  #include "predict.h"
+ #include "except.h"
+ #include "libfuncs.h"
  
  /* If non-NULL, the address of a language-specific function for
     expanding statements.  */
*************** genrtl_decl_cleanup (t)
*** 762,767 ****
--- 764,813 ----
      expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
  }
  
+ /* Generate the RTL for a TRY_FINALLY_STMT.  */
+ 
+ void
+ genrtl_try_finally_stmt (t)
+      tree t;
+ {
+   tree try_block, finally_block;
+   static bool eh_initialized_p;
+ 
+   if (!TRY_FINALLY_FINALLY (t))
+     {
+       /* For a C++ try-block, we create both a TRY_FINALLY_STMT and a
+ 	 TRY_BLOCK, even if one of them is unnecessary.  We have to do this
+ 	 because they need to be added before the contents of the
+ 	 try-block.  Hopefully this will be fixed with the new parser.
+ 
+          If there's no finally block, ignore the TRY_FINALLY_STMT.  */
+       expand_stmt (TRY_FINALLY_TRY (t));
+       return;
+     }
+ 
+   if (flag_exceptions && !eh_initialized_p)
+     {
+       eh_initialized_p = true;
+       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
+ 						 ? "__gcc_personality_sj0"
+ 						 : "__gcc_personality_v0");
+       using_eh_for_cleanups ();
+     }
+ 
+   try_block = TRY_FINALLY_TRY (t);
+   finally_block = TRY_FINALLY_FINALLY (t);
+ 
+   try_block = build1 (STMT_EXPR, void_type_node, try_block);
+   finally_block = build1 (STMT_EXPR, void_type_node, finally_block);
+   TREE_SIDE_EFFECTS (try_block) = 1;
+   TREE_SIDE_EFFECTS (finally_block) = 1;
+ 
+   /* Wrap in TRY_FINALLY_EXPR and punt it off.  */
+   t = build (TRY_FINALLY_EXPR, void_type_node, try_block, finally_block);
+   expand_expr (t, NULL, VOIDmode, EXPAND_NORMAL);
+   return;
+ }
+ 
  /* We're about to expand T, a statement.  Set up appropriate context
     for the substitution.  */
  
*************** expand_stmt (t)
*** 874,879 ****
--- 920,929 ----
  
  	case CLEANUP_STMT:
  	  genrtl_decl_cleanup (t);
+ 	  break;
+ 
+ 	case TRY_FINALLY_STMT:
+ 	  genrtl_try_finally_stmt (t);
  	  break;
  
  	default:
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.105.4.2
diff -c -p -r1.105.4.2 c-tree.h
*** c-tree.h	17 Sep 2002 22:58:37 -0000	1.105.4.2
--- c-tree.h	5 Nov 2002 23:01:39 -0000
*************** extern void c_finish_case               
*** 296,301 ****
--- 296,302 ----
  extern tree simple_asm_stmt			PARAMS ((tree));
  extern tree build_asm_stmt			PARAMS ((tree, tree, tree,
  							 tree, tree));
+ extern tree build_try_finally_stmt		PARAMS ((tree, tree));
  extern tree c_convert_parm_for_inlining		PARAMS ((tree, tree, tree));
  
  /* Set to 0 at beginning of a function definition, set to 1 if
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.203.4.5
diff -c -p -r1.203.4.5 c-typeck.c
*** c-typeck.c	15 Oct 2002 01:32:45 -0000	1.203.4.5
--- c-typeck.c	5 Nov 2002 23:01:44 -0000
*************** build_asm_stmt (cv_qualifier, string, ou
*** 6904,6909 ****
--- 6904,6919 ----
  			       outputs, inputs, clobbers));
  }
  
+ tree
+ build_try_finally_stmt (try_block, finally_block)
+      tree try_block, finally_block;
+ {
+   tree t;
+ 
+   t = build (TRY_FINALLY_STMT, void_type_node, try_block, finally_block);
+   return t;
+ }
+ 
  /* Expand an ASM statement with operands, handling output operands
     that are not variables or INDIRECT_REFS by transforming such
     cases into cases that expand_asm_operands can handle.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.366.4.6
diff -c -p -r1.366.4.6 c-common.c
*** c-common.c	21 Oct 2002 17:51:51 -0000	1.366.4.6
--- c-common.c	5 Nov 2002 23:01:48 -0000
*************** statement_code_p (code)
*** 3914,3919 ****
--- 3914,3920 ----
      case ASM_STMT:
      case FILE_STMT:
      case CASE_LABEL:
+     case TRY_FINALLY_STMT:
        return 1;
  
      default:
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.154.4.3
diff -c -p -r1.154.4.3 c-common.h
*** c-common.h	1 Oct 2002 17:31:37 -0000	1.154.4.3
--- c-common.h	5 Nov 2002 23:01:49 -0000
*************** enum rid
*** 77,82 ****
--- 77,83 ----
    RID_ASM,       RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
    RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
    RID_PTREXTENT, RID_PTRVALUE, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P,
+   RID_FINALLY,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
*************** extern tree strip_array_types           
*** 1097,1102 ****
--- 1098,1110 ----
  #define FILE_STMT_FILENAME(NODE) \
    (IDENTIFIER_POINTER (FILE_STMT_FILENAME_NODE (NODE)))
  
+ /* The try block of a try/finally construct.  */
+ #define TRY_FINALLY_TRY(NODE) \
+   (TREE_OPERAND (TRY_FINALLY_STMT_CHECK (NODE), 0))
+ /* The finally block of a try/finally construct.  */
+ #define TRY_FINALLY_FINALLY(NODE) \
+   (TREE_OPERAND (TRY_FINALLY_STMT_CHECK (NODE), 1))
+ 
  /* The line-number at which a statement began.  But if
     STMT_LINENO_FOR_FN_P does holds, then this macro gives the
     line number for the end of the current function instead.  */
*************** extern void genrtl_asm_stmt             
*** 1146,1151 ****
--- 1154,1160 ----
  							 tree, tree,
  							 tree, int));
  extern void genrtl_decl_cleanup                 PARAMS ((tree));
+ extern void genrtl_try_finally_stmt		PARAMS ((tree));
  extern int stmts_are_full_exprs_p               PARAMS ((void));
  extern int anon_aggr_type_p                     PARAMS ((tree));
  
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.152
diff -c -p -r1.152 c-parse.in
*** c-parse.in	15 Aug 2002 21:16:23 -0000	1.152
--- c-parse.in	5 Nov 2002 23:01:51 -0000
*************** do {									\
*** 150,155 ****
--- 150,156 ----
  %token ATTRIBUTE EXTENSION LABEL
  %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
  %token PTR_VALUE PTR_BASE PTR_EXTENT
+ %token TRY FINALLY
  
  /* function name can be a string const or a var decl. */
  %token STRING_FUNC_NAME VAR_FUNC_NAME
*************** do {									\
*** 212,218 ****
  %type <ttype> any_word extension
  
  %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
! %type <ttype> do_stmt_start poplevel stmt label
  
  %type <ttype> c99_block_start c99_block_end
  %type <ttype> declarator
--- 213,219 ----
  %type <ttype> any_word extension
  
  %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
! %type <ttype> do_stmt_start poplevel stmt label try_finally_begin
  
  %type <ttype> c99_block_start c99_block_end
  %type <ttype> declarator
*************** for_init_stmt:
*** 2363,2372 ****
--- 2364,2386 ----
  		{ check_for_loop_decls (); }
  	;
  
+ try_finally_begin: TRY
+ 		{
+ 		  $$ = add_stmt (build_stmt (TRY_FINALLY_STMT, NULL_TREE));
+ 		}
+ 		;
+ 
  /* Parse a single real statement, not including any labels.  */
  stmt:
  	  compstmt
  		{ stmt_count++; $$ = $1; }
+ 	| try_finally_begin compstmt
+ 		{ RECHAIN_STMTS ($1, TRY_FINALLY_TRY ($1)); }
+ 		FINALLY compstmt
+ 		{ stmt_count++;
+ 		  RECHAIN_STMTS ($1, TRY_FINALLY_FINALLY ($1));
+ 		  $$ = $1;
+ 		}
  	| expr ';'
  		{ stmt_count++;
  		  $$ = c_expand_expr_stmt ($1); }
*************** static const struct resword reswords[] =
*** 3322,3327 ****
--- 3336,3342 ----
    { "__const",		RID_CONST,	0 },
    { "__const__",	RID_CONST,	0 },
    { "__extension__",	RID_EXTENSION,	0 },
+   { "__finally",	RID_FINALLY, 0 },
    { "__func__",		RID_C99_FUNCTION_NAME, 0 },
    { "__imag",		RID_IMAGPART,	0 },
    { "__imag__",		RID_IMAGPART,	0 },
*************** static const struct resword reswords[] =
*** 3341,3346 ****
--- 3356,3362 ----
    { "__signed",		RID_SIGNED,	0 },
    { "__signed__",	RID_SIGNED,	0 },
    { "__thread",		RID_THREAD,	0 },
+   { "__try",		RID_TRY,	0 },
    { "__typeof",		RID_TYPEOF,	0 },
    { "__typeof__",	RID_TYPEOF,	0 },
    { "__unbounded",	RID_UNBOUNDED,	0 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3493,3498 ****
--- 3509,3516 ----
    /* RID_CHOOSE_EXPR */			CHOOSE_EXPR,
    /* RID_TYPES_COMPATIBLE_P */		TYPES_COMPATIBLE_P,
  
+   /* RID_FINALLY */			FINALLY,
+ 
    /* RID_FUNCTION_NAME */		STRING_FUNC_NAME,
    /* RID_PRETTY_FUNCTION_NAME */	STRING_FUNC_NAME,
    /* RID_C99_FUNCTION_NAME */		VAR_FUNC_NAME,
*************** static const short rid_to_yy[RID_MAX] =
*** 3515,3521 ****
    /* RID_THIS */	0,
    /* RID_THROW */	0,
    /* RID_TRUE */	0,
!   /* RID_TRY */		0,
    /* RID_TYPENAME */	0,
    /* RID_TYPEID */	0,
    /* RID_USING */	0,
--- 3533,3539 ----
    /* RID_THIS */	0,
    /* RID_THROW */	0,
    /* RID_TRUE */	0,
!   /* RID_TRY */		TRY,
    /* RID_TYPENAME */	0,
    /* RID_TYPEID */	0,
    /* RID_USING */	0,
Index: config/t-linux
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/t-linux,v
retrieving revision 1.12
diff -c -p -r1.12 t-linux
*** config/t-linux	15 Dec 2001 11:46:55 -0000	1.12
--- config/t-linux	5 Nov 2002 23:01:51 -0000
*************** SHLIB_MAPFILES += $(srcdir)/config/libgc
*** 12,16 ****
  
  # Use unwind-dw2-fde-glibc
  LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
!   $(srcdir)/unwind-sjlj.c
  LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
--- 12,16 ----
  
  # Use unwind-dw2-fde-glibc
  LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
!   $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
  LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
Index: config/ia64/t-ia64
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/t-ia64,v
retrieving revision 1.13.20.2
diff -c -p -r1.13.20.2 t-ia64
*** config/ia64/t-ia64	17 Sep 2002 22:59:00 -0000	1.13.20.2
--- config/ia64/t-ia64	5 Nov 2002 23:01:51 -0000
*************** crtendS.o: $(srcdir)/config/ia64/crtend.
*** 34,40 ****
  crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/ia64/crtfastmath.c
  
! LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c
  
  ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
      $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
--- 34,41 ----
  crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/ia64/crtfastmath.c
  
! LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c $(srcdir
! )/unwind-c.c
  
  ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
      $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
Index: testsuite/gcc.c-torture/execute/try-finally-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/try-finally-1.c
diff -N testsuite/gcc.c-torture/execute/try-finally-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/execute/try-finally-1.c	5 Nov 2002 23:01:51 -0000
***************
*** 0 ****
--- 1,43 ----
+ int caught;
+ 
+ void doit (void)
+ {
+   __try {
+     return;
+   } __finally {
+     caught = 1;
+   }
+ }
+ 
+ void doit_again (void)
+ {
+   caught = 0;
+ 
+   while (1) {
+     __try {
+       __try {
+ 	return;
+       } __finally {
+ 	caught = 1;
+       }
+     } __finally {
+       if (!caught)
+ 	abort ();
+       caught = 2;
+     }
+   }
+   abort ();
+ }
+ 
+ int main ()
+ {
+   doit ();
+   if (caught != 1)
+     abort ();
+ 
+   doit_again ();
+   if (caught != 2)
+     abort ();
+ 
+   return 0;
+ }
Index: testsuite/gcc.c-torture/execute/try-finally-2.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/try-finally-2.c
diff -N testsuite/gcc.c-torture/execute/try-finally-2.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/execute/try-finally-2.c	5 Nov 2002 23:01:51 -0000
***************
*** 0 ****
--- 1,26 ----
+ int caught;
+ 
+ void doit (int i)
+ {
+   caught = 0;
+   __try {
+     if (!i)
+       return;
+   } __finally {
+     caught = 1;
+   }
+   caught = 2;
+ }
+ 
+ int main ()
+ {
+   doit (0);
+   if (caught != 1)
+     abort ();
+ 
+   doit (1);
+   if (caught != 2)
+     abort ();
+ 
+   return 0;
+ }
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.289.4.3
diff -c -p -r1.289.4.3 lex.c
*** cp/lex.c	21 Oct 2002 17:52:56 -0000	1.289.4.3
--- cp/lex.c	5 Nov 2002 23:01:52 -0000
*************** static const struct resword reswords[] =
*** 345,350 ****
--- 345,351 ----
    { "__const__",	RID_CONST,	0 },
    { "__extension__",	RID_EXTENSION,	0 },
    { "__func__",		RID_C99_FUNCTION_NAME,	0 },
+   { "__finally",	RID_FINALLY, 0 },
    { "__imag",		RID_IMAGPART,	0 },
    { "__imag__",		RID_IMAGPART,	0 },
    { "__inline",		RID_INLINE,	0 },
*************** static const struct resword reswords[] =
*** 358,363 ****
--- 359,365 ----
    { "__signed",		RID_SIGNED,	0 },
    { "__signed__",	RID_SIGNED,	0 },
    { "__thread",		RID_THREAD,	0 },
+   { "__try",		RID_TRY,	0 },
    { "__typeof",		RID_TYPEOF,	0 },
    { "__typeof__",	RID_TYPEOF,	0 },
    { "__volatile",	RID_VOLATILE,	0 },
*************** const short rid_to_yy[RID_MAX] =
*** 507,512 ****
--- 509,515 ----
    /* RID_PTRVALUE */	0,
    /* RID_CHOOSE_EXPR */	0,
    /* RID_TYPES_COMPATIBLE_P */ 0,
+   /* RID_FINALLY */ FINALLY,
  
    /* RID_FUNCTION_NAME */	VAR_FUNC_NAME,
    /* RID_PRETTY_FUNCTION_NAME */ VAR_FUNC_NAME,
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.744.4.7
diff -c -p -r1.744.4.7 cp-tree.h
*** cp/cp-tree.h	21 Oct 2002 17:52:51 -0000	1.744.4.7
--- cp/cp-tree.h	5 Nov 2002 23:01:55 -0000
*************** extern void finish_handler_parms        
*** 4106,4111 ****
--- 4106,4113 ----
  extern void begin_catch_block                   PARAMS ((tree));
  extern void finish_handler                      PARAMS ((tree));
  extern void finish_cleanup                      PARAMS ((tree, tree));
+ extern void finish_try_finally_try            	PARAMS ((tree));
+ extern void finish_try_finally_finally          PARAMS ((tree));
  extern tree begin_compound_stmt                 PARAMS ((int));
  extern tree finish_compound_stmt                PARAMS ((int, tree));
  extern tree finish_asm_stmt                     PARAMS ((tree, tree, tree, tree, tree));
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.279.4.3
diff -c -p -r1.279.4.3 parse.y
*** cp/parse.y	21 Oct 2002 17:52:57 -0000	1.279.4.3
--- cp/parse.y	5 Nov 2002 23:01:57 -0000
*************** check_class_key (key, aggr)
*** 323,328 ****
--- 323,329 ----
  %token SIGOF
  %token ATTRIBUTE EXTENSION LABEL
  %token REALPART IMAGPART VA_ARG
+ %token FINALLY
  
  /* the reserved words... C++ extensions */
  %token <ttype> AGGR
*************** check_class_key (key, aggr)
*** 463,468 ****
--- 464,470 ----
  %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
  %type <ttype> handler_args
  %type <ttype> self_template_type finish_template_type_
+ %type <itype> handler_seq finally_stmt
  
  %token NSNAME
  %type <ttype> NSNAME
*************** function_try_block:
*** 3552,3575 ****
  
  try_block:
  	  TRY
!                 { $<ttype>$ = begin_try_block (); }
  	  compstmt
                  { finish_try_block ($<ttype>2); }
  	  handler_seq
!                 { finish_handler_sequence ($<ttype>2); }
  	;
  
  handler_seq:
  	  handler
  	| handler_seq handler
  	| /* empty */
  		{ /* Generate a fake handler block to avoid later aborts. */
  		  tree fake_handler = begin_handler ();
  		  finish_handler_parms (NULL_TREE, fake_handler);
  		  finish_handler (fake_handler);
! 		  $<ttype>$ = fake_handler;
! 
! 		  error ("must have at least one catch per try block");
  		}
  	;
  
--- 3554,3597 ----
  
  try_block:
  	  TRY
!                 {
! 		  $<ttype>1 = begin_try_finally ();
! 		  $<ttype>$ = begin_try_block ();
! 		}
  	  compstmt
                  { finish_try_block ($<ttype>2); }
  	  handler_seq
!                 {
! 		  finish_handler_sequence ($<ttype>2);
! 		  finish_try_finally_try ($<ttype>1);
! 		}
! 	  finally_stmt
! 	  	{
! 		  finish_try_finally_finally ($<ttype>1);
! 
! 		  if (!$5 && !$7)
! 		    error ("must have at least one catch per try block");
! 		}
! 	;
! 
! finally_stmt:
! 	  FINALLY compstmt
! 		{ $$ = 1; }
! 	| /* empty */
! 		{ $$ = 0; }
  	;
  
  handler_seq:
  	  handler
+ 		{ $$ = 1; }
  	| handler_seq handler
+ 		{ $$ = 1; }
  	| /* empty */
  		{ /* Generate a fake handler block to avoid later aborts. */
  		  tree fake_handler = begin_handler ();
  		  finish_handler_parms (NULL_TREE, fake_handler);
  		  finish_handler (fake_handler);
! 		  $$ = 0;
  		}
  	;
  
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.610.4.4
diff -c -p -r1.610.4.4 pt.c
*** cp/pt.c	15 Oct 2002 01:33:31 -0000	1.610.4.4
--- cp/pt.c	5 Nov 2002 23:02:04 -0000
*************** tsubst_expr (t, args, complain, in_decl)
*** 7657,7662 ****
--- 7657,7671 ----
  	    finish_handler_sequence (stmt);
  	}
        break;
+ 
+     case TRY_FINALLY_STMT:
+       prep_stmt (t);
+       stmt = begin_try_finally ();
+       tsubst_expr (TRY_FINALLY_TRY (t), args, complain, in_decl);
+       finish_try_finally_try (stmt);
+       tsubst_expr (TRY_FINALLY_FINALLY (t), args, complain, in_decl);
+       finish_try_finally_finally (stmt);
+       break;
        
      case HANDLER:
        {
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.274.4.5
diff -c -p -r1.274.4.5 semantics.c
*** cp/semantics.c	21 Oct 2002 17:52:57 -0000	1.274.4.5
--- cp/semantics.c	5 Nov 2002 23:02:05 -0000
*************** static void 
*** 598,603 ****
--- 598,615 ----
  genrtl_try_block (t)
       tree t;
  {
+   if (!TRY_HANDLERS (t))
+     {
+       /* For a C++ try-block, we create both a TRY_FINALLY_STMT and a
+ 	 TRY_BLOCK, even if one of them is unnecessary.  We have to do this
+ 	 because they need to be added before the contents of the
+ 	 try-block.  Hopefully this will be fixed with the new parser.
+ 
+          If there are no handlers, ignore the TRY_BLOCK.  */
+       expand_stmt (TRY_STMTS (t));
+       return;
+     }
+ 
    if (CLEANUP_P (t))
      {
        expand_eh_region_start ();
*************** finish_handler (handler)
*** 805,810 ****
--- 817,854 ----
      expand_end_catch_block ();
    do_poplevel ();
    RECHAIN_STMTS (handler, HANDLER_BODY (handler));
+ }
+ 
+ /* Begin a try/finally construct.  The parser calls this immediately before
+    begin_try_block, as one 'try' could start either a normal C++ try-block,
+    a try/finally construct, or both.  */
+ 
+ tree
+ begin_try_finally ()
+ {
+   tree r = build_stmt (TRY_FINALLY_STMT, NULL_TREE, NULL_TREE);
+   add_stmt (r);
+   return r;
+ }
+ 
+ /* Finish the body of a try/finally construct.  This usually consists of a
+    TRY_BLOCK.  */
+ 
+ void
+ finish_try_finally_try (try_finally)
+      tree try_finally;
+ {
+   RECHAIN_STMTS (try_finally, TRY_FINALLY_TRY (try_finally));
+ }
+ 
+ /* Finish the finally block of a try/finally construct.  This will be
+    NULL_TREE in the case of a normal C++ try-block.  */
+ 
+ void
+ finish_try_finally_finally (try_finally)
+      tree try_finally;
+ {
+   RECHAIN_STMTS (try_finally, TRY_FINALLY_FINALLY (try_finally));
  }
  
  /* Begin a compound-statement.  If HAS_NO_SCOPE is nonzero, the
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.95.4.5
diff -c -p -r1.95.4.5 extend.texi
*** doc/extend.texi	21 Oct 2002 17:52:59 -0000	1.95.4.5
--- doc/extend.texi	5 Nov 2002 23:02:12 -0000
*************** extensions, accepted by GCC in C89 mode 
*** 473,478 ****
--- 473,479 ----
  * Target Builtins::     Built-in functions specific to particular targets.
  * Pragmas::             Pragmas accepted by GCC.
  * Unnamed Fields::      Unnamed struct/union fields within structs/unions.
+ * Try-finally::         Try/finally construct.
  * Thread-Local::        Per-thread variables.
  @end menu
  
*************** struct @{
*** 6506,6511 ****
--- 6507,6715 ----
  It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
  Such constructs are not supported and must be avoided.  In the future,
  such constructs may be detected and treated as compilation errors.
+ 
+ @node Try-finally
+ @section Try/finally exceptions
+ @cindex Try/finally exceptions
+ @cindex try-finally
+ @cindex __try
+ @cindex __finally
+ 
+ The @code{__try/__finally} statement consists of a @code{__try} block
+ containing one or statements, and a @code{__finally} block contatining
+ one or more statements.  The @code{__finally} block will execute after
+ the @code{__try} block but before the code following the
+ @code{__try/__finally} construct, even if the @code{__try} block exits
+ the current function.
+ 
+ For example:
+ 
+ @example
+ __try @{
+   do_something();
+   return;
+ @} __finally @{
+   fin = 1;
+ @}
+ @end example
+ 
+ In the above example, @code{fin} will get set to 1 before the function
+ returns to its caller.
+ 
+ You can nest more than one @code{__try/__finally} construct.
+ 
+ Since C++ already has a @code{try} keyword, both @code{try} and
+ @code{__try} variations are allowed.  Also, the C++ implementation
+ allows using @code{__finally} after a series of @code{try/catch}
+ blocks.  The @code{__finally} code will be executed after the
+ applicable @code{catch}.  For example:
+ 
+ @example
+ try @{
+   do_something();
+ @} catch (blah) @{
+   x = 0;
+ @} catch (...) @{
+   x = 1;
+ @} __finally @{
+   y = 2;
+ @}
+ @end example
+ 
+ In the example above, @code{y} will be set after the set to @code{x}
+ in the catch clause.
+ 
+ It is possible to have a C @code{__try/__finally} construct call C++
+ code that throws an exception.  As part of the unwind process, the C
+ @code{__finally} block will be called before control is returned to
+ the C's calling routine.
+ 
+ Exiting out of a finally block through a @code{return} or @code{goto}
+ has undefined behaviour.
+ 
+ GCC's @code{__try/__finally} implementation is analogous to the
+ corresponding construct in Java.
+ 
+ @menu
+ * C99 Try-Finally Edits::
+ * C++98 Try-Finally Edits::
+ @end menu
+ 
+ @node C99 Try-Finally Edits
+ @subsection ISO/IEC 9899:1999 Edits for Try-Finally
+ 
+ The following are a set of changes to ISO/IEC 9899:1999 (aka C99)
+ that document the exact semantics of the language extension.
+ 
+ @itemize @bullet
+ @item
+ @cite{6.4.1  Keywords}
+ 
+ Add @code{__try}.
+ Add @code{__finally}.
+ 
+ @item
+ @cite{6.8.2b  The try/finally statement}
+ 
+ New section.
+ 
+ @quotation
+ Syntax:
+ @example
+         try-finally-statement:
+            @b{__try}
+                 @b{@{} block-item-list @b{@}}
+            @b{__finally}
+                 @b{@{} block-item-list @b{@}}
+         
+ @end example
+ @end quotation
+ 
+ The @code{__try} block is executed.  After the __try block exits,
+ control is transferred to the @code{__finally} block regardless of how
+ the __try block exits.
+ 
+ The __finally block is guaranteed to execute after the __try block,
+ provided the program does not terminate while inside such block.
+ After the __finally block executes, the flow of the program will
+ continue where the __try block was meant to transfer control to, had
+ there been no __finally block.
+ 
+ This construct is meant to provide a mechanism through which a series
+ of cleanups can be executed upon exit from a block (the __try block).
+ If somewhere inside the __try block an exception occurs and the
+ corresponding exception handler lies in the frame above the __finally
+ block, the __finally block will execute before control reaches the
+ exception handler above.
+ 
+ This mechanism is by no ways a complete exception handling system for
+ C.
+ 
+ @end itemize
+ 
+ @node C++98 Try-Finally Edits
+ @subsection ISO/IEC 14882:1998 Edits for Try-Finally
+ 
+ @itemize @bullet
+ @item
+ @cite{2.11 Keywords: Table 3}
+ 
+ Add @code{__finally}.
+ Add @code{finally}.
+ 
+ @item
+ @cite{15  Exception handling}
+ 
+ Rename the @code{handler-seq} production by the following:
+ 
+ @example
+         handler-seq:
+                 handler-seq-catch finally-block
+ 
+         handler-seq-catch:
+                 handler handler-seq-catch
+ 
+         finally-block:
+                 @b{__finally} compound-statement
+ @end example
+ 
+ Add new text at the end of section 2.
+ 
+ @quotation
+ Before control is transferred to the desired destination, the
+ __finally block is executed.  After such block is executed, control is
+ transferred to the desired destination.
+ @end quotation
+ 
+ Add to code below to the example in section 3.
+ 
+ @example
+         __finally
+         @{
+                 // code to be executed after the try block and
+                 // applicable catch block is executed.
+         @}
+ @end example
+ 
+ @item
+ @cite{15.1  Throwing an exception}
+ 
+ Add new section before section 2 and 3.
+ 
+ @quotation
+ After an exception is caught by an applicable handler (if present),
+ but before control is transferred elsewhere (provided the program does
+ not exit), the code in the __finally block is executed.
+ @end quotation
+ 
+ @item
+ @cite{15.2  Constructors and destructors}
+ 
+ Add new text to section 3.
+ 
+ @quotation
+ If code within a @i{try} block (or within code called from a try
+ block) causes an exception that is not caught by the subsequent
+ @i{catch} blocks, the code in @i{__finally} executes as the stack
+ unwinds upwards.
+ @end quotation
+ 
+ Add new text to section 7.
+ 
+ @quotation
+ If the try block has a corresponding __finally block, the code in the
+ __finally block will execute before control reaches the dynamically
+ surrounding try block.
+ @end quotation
+ 
+ Add new section 2.
+ 
+ @quotation
+ If the __finally block contains a jump outside stated block, the
+ program is ill-formed and the behavior is undefined.
+ @end quotation
+ 
+ @end itemize
  
  @node Thread-Local
  @section Thread-Local Storage

^ permalink raw reply	[flat|nested] 128+ messages in thread

end of thread, other threads:[~2002-11-12 16:58 UTC | newest]

Thread overview: 128+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-05 15:16 [basic-improvements] try/finally support for c/c++ Aldy Hernandez
2002-11-05 15:57 ` Richard Henderson
2002-11-05 23:03   ` Aldy Hernandez
2002-11-06  0:44     ` Joseph S. Myers
2002-11-06  0:52       ` Jakub Jelinek
2002-11-06  3:02         ` Michael Matz
2002-11-06  3:11           ` Jakub Jelinek
2002-11-06  4:16             ` Michael Matz
2002-11-06 10:29       ` Aldy Hernandez
2002-11-06 10:53         ` Richard Henderson
2002-11-06 10:56           ` Aldy Hernandez
2002-11-06 11:24           ` Joseph S. Myers
2002-11-06 13:49             ` Richard Henderson
2002-11-06 17:45           ` Fergus Henderson
2002-11-07  9:54             ` Richard Henderson
2002-11-06 17:48           ` Fergus Henderson
2002-11-07  9:58             ` Richard Henderson
2002-11-06 11:22         ` Joseph S. Myers
2002-11-06 14:00           ` Richard Henderson
2002-11-06 17:21         ` Fergus Henderson
2002-11-06  4:20   ` Gabriel Dos Reis
2002-11-06  9:05     ` Aldy Hernandez
2002-11-06  9:11       ` Matt Austern
2002-11-06  9:25         ` Gabriel Dos Reis
2002-11-06 11:15         ` Richard Henderson
2002-11-07  0:09           ` Kai Henningsen
2002-11-07 12:56             ` Richard Henderson
2002-11-06  6:05   ` Jason Merrill
2002-11-06 10:56     ` Richard Henderson
2002-11-06 12:14       ` Jason Merrill
2002-11-05 16:40 ` Stan Shebs
2002-11-05 16:48   ` Matt Austern
2002-11-05 17:21     ` Jason Merrill
2002-11-05 19:25       ` Matt Austern
2002-11-06 10:25         ` Richard Henderson
2002-11-06 11:05         ` Mike Stump
2002-11-05 21:20     ` Aldy Hernandez
2002-11-06  9:43 ` [basic-improvements] try/finally support for c/c++ - more tests Jakub Jelinek
2002-11-06 11:04   ` Joseph S. Myers
2002-11-06 15:34   ` Mark Mitchell
2002-11-06 16:03     ` Richard Henderson
2002-11-06 16:10       ` Gabriel Dos Reis
2002-11-06 16:12         ` Richard Henderson
2002-11-06 16:20           ` Gabriel Dos Reis
2002-11-06 17:02             ` Per Bothner
2002-11-06 17:14               ` Gabriel Dos Reis
2002-11-06 16:47       ` Mark Mitchell
2002-11-06 16:54         ` Matt Austern
2002-11-06 18:00         ` Zack Weinberg
2002-11-06 18:14           ` Gabriel Dos Reis
2002-11-06 18:58             ` Zack Weinberg
2002-11-06 19:33               ` Gabriel Dos Reis
2002-11-06 22:15                 ` Zack Weinberg
2002-11-06 22:37           ` Mark Mitchell
2002-11-06 23:30             ` Aldy Hernandez
2002-11-07  1:03               ` Gabriel Dos Reis
2002-11-07  5:34             ` Michael Matz
2002-11-07  8:14               ` Mark Mitchell
2002-11-07  8:37                 ` Daniel Jacobowitz
2002-11-07  9:09                   ` Mark Mitchell
2002-11-07  9:19                     ` Daniel Jacobowitz
2002-11-07  9:53                       ` Mark Mitchell
2002-11-07  9:57                         ` Matt Austern
2002-11-07 10:43                         ` Jason Merrill
2002-11-07  8:44                 ` Jakub Jelinek
2002-11-07 12:18                 ` Geoff Keating
2002-11-07 12:24                   ` Daniel Jacobowitz
2002-11-07 12:32                   ` Mark Mitchell
2002-11-07 13:41                     ` Geoff Keating
2002-11-07 14:06                       ` Mark Mitchell
2002-11-07 14:39                         ` Richard Henderson
2002-11-07 14:53                           ` Mark Mitchell
2002-11-07 15:14                             ` Geoff Keating
2002-11-07 15:37                               ` Mark Mitchell
2002-11-08 11:30                                 ` Geoff Keating
2002-11-07 15:45                             ` Richard Henderson
2002-11-07 16:21                               ` Mark Mitchell
2002-11-07 16:44                                 ` aldyh
2002-11-07 17:06                                 ` Richard Henderson
2002-11-07 17:10                                 ` Jakub Jelinek
2002-11-07 17:29                                   ` Mark Mitchell
2002-11-07 17:43                                     ` Richard Henderson
2002-11-07 17:55                                       ` Mark Mitchell
2002-11-07 17:52                                     ` Jason Merrill
2002-11-07 17:57                                       ` Mark Mitchell
2002-11-07 18:17                                         ` Zack Weinberg
2002-11-07 18:29                                           ` Mark Mitchell
2002-11-07 21:23                                             ` Robert Lipe
2002-11-07 21:32                                               ` Jason Merrill
2002-11-08  4:48                                             ` Nicola Pero
2002-11-08  5:47                                               ` Jakub Jelinek
2002-11-08 10:02                                                 ` Fergus Henderson
2002-11-08 11:24                                                 ` Kai Henningsen
2002-11-08 11:44                                                   ` Jakub Jelinek
2002-11-09  0:11                                                     ` Fergus Henderson
2002-11-08 11:46                                                   ` Mike Stump
2002-11-08 10:02                                             ` Matt Austern
2002-11-11  5:38                                               ` Michael Matz
2002-11-11 12:59                                                 ` Matt Austern
2002-11-12  1:01                                                   ` Michael Matz
2002-11-12  8:20                                                     ` Mark Mitchell
2002-11-12  8:58                                                       ` Michael Matz
2002-11-07 19:28                                         ` Daniel Jacobowitz
2002-11-07 22:07                                 ` Alexandre Oliva
2002-11-08  4:27                                   ` Richard Henderson
2002-11-08  4:54                                     ` Jakub Jelinek
2002-11-08  6:01                                       ` Jakub Jelinek
2002-11-08 11:38                                       ` Mike Stump
2002-11-08 11:25                                     ` Mike Stump
2002-11-08  9:31                                 ` Michael Matz
2002-11-08 11:26                                   ` Hans-Peter Nilsson
2002-11-08 11:48                                     ` Mike Stump
2002-11-07 11:38               ` Zack Weinberg
2002-11-07  9:38             ` Mike Stump
2002-11-07 10:06           ` Richard Henderson
2002-11-07 12:57           ` Hans-Peter Nilsson
2002-11-06 17:58       ` Fergus Henderson
2002-11-06 18:09         ` Fergus Henderson
2002-11-07  0:30         ` Jakub Jelinek
2002-11-06 18:34       ` Geoff Keating
2002-11-07  3:29         ` Fergus Henderson
2002-11-07  4:22           ` Jakub Jelinek
2002-11-07  5:13             ` Fergus Henderson
2002-11-07  5:47               ` Michael Matz
2002-11-07  8:52               ` Aldy Hernandez
2002-11-07 10:00                 ` Mike Stump
2002-11-07 12:36                 ` Alexandre Oliva
2002-11-07 13:06                   ` Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).