OSDN Git Service

Have -fnew-exceptions actually use the runtime field, and not generate
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jun 1998 07:10:29 +0000 (07:10 +0000)
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jun 1998 07:10:29 +0000 (07:10 +0000)
runtime checking code inside each handler.
THis works at low opt, but not with optimization at the moment.
Tue Jun 23 10:06:07 EDT 1998  Andrew MacLeod  (amacleod@cygnus.com)
* eh-common.h (struct __eh_info): Remove coerced value field.
* libgcc2.c (find_exception_handler): Don't set coerced_value field.
* except.c (get_dynamic_handler_chain, get_dynamic_cleanup_chain): Use
POINTER_SIZE instead of Pmode.
(expand_start_all_catch): Call start_catch_handler() if we are not
using new style exceptions.
1998-06-22  Andrew MacLeod  (amacleod@cygnus.com)
* parse.y (function_try_block): Don't call start_catch_handler.
* except.c (call_eh_info): Remove coerced field from declaration.
(build_eh_type_type_ref): New function to create an address of a
rtti function for the new style exception tables.
(expand_start_catch_block): Split function, this contains the
common part.
(process_start_catch_block_old): New function to perform the rest
of expand_start_catch_block under old style exceptions.
(process_start_catch_block_old): New function to perform the rest
of expand_start_catch_block under new style exceptions.
(expand_end_catch_block): Only pop the false label off the stack under
the old style of exceptions.
* semantics.c (finish_try_block): Don't call start_catch_handler.
* exception.cc (struct cp_eh_info): Add original_value field.
(__cplus_type_matcher): Perform type matching on the original exception
value, and if we have a match, set the current value.
(__cp_push_exception): Set the original expcetion value.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20671 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/except.c
gcc/cp/exception.cc
gcc/cp/parse.y
gcc/cp/semantics.c
gcc/eh-common.h
gcc/except.c
gcc/libgcc2.c

index 69b80ca..d4f3d45 100644 (file)
@@ -1,3 +1,12 @@
+Tue Jun 23 10:06:07 EDT 1998  Andrew MacLeod  (amacleod@cygnus.com)
+
+       * eh-common.h (struct __eh_info): Remove coerced value field.
+       * libgcc2.c (find_exception_handler): Don't set coerced_value field.
+       * except.c (get_dynamic_handler_chain, get_dynamic_cleanup_chain): Use 
+       POINTER_SIZE instead of Pmode.
+       (expand_start_all_catch): Call start_catch_handler() if we are not
+       using new style exceptions.
+
 Tue Jun 23 06:45:00 1998  Catherine Moore  <clm@cygnus.com>
 
         * varasm.c (assemble_variable): Remove reference to warn_bss_align.
index 27a8178..ddd56db 100644 (file)
@@ -1,3 +1,23 @@
+1998-06-23  Andrew MacLeod  (amacleod@cygnus.com)
+
+       * parse.y (function_try_block): Don't call start_catch_handler.
+       * except.c (call_eh_info): Remove coerced field from declaration.
+       (build_eh_type_type_ref): New function to create an address of a
+       rtti function for the new style exception tables.
+       (expand_start_catch_block): Split function, this contains the
+       common part.
+       (process_start_catch_block_old): New function to perform the rest
+       of expand_start_catch_block under old style exceptions.
+       (process_start_catch_block_old): New function to perform the rest
+       of expand_start_catch_block under new style exceptions.
+       (expand_end_catch_block): Only pop the false label off the stack under
+       the old style of exceptions.
+       * semantics.c (finish_try_block): Don't call start_catch_handler.
+       * exception.cc (struct cp_eh_info): Add original_value field.
+       (__cplus_type_matcher): Perform type matching on the original exception
+       value, and if we have a match, set the current value.
+       (__cp_push_exception): Set the original expcetion value.
+
 1998-06-23  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (joust): Fix confusing conversion warning.
index dba0f09..438351e 100644 (file)
@@ -56,6 +56,9 @@ static tree get_eh_type PROTO((void));
 static tree get_eh_caught PROTO((void));
 static tree get_eh_handlers PROTO((void));
 static tree do_pop_exception PROTO((void));
+static void process_start_catch_block PROTO((tree, tree));
+static void process_start_catch_block_old PROTO((tree, tree));
+static tree build_eh_type_type_ref PROTO((tree));
 
 #if 0
 /* This is the startup, and finish stuff per exception table.  */
@@ -273,14 +276,12 @@ call_eh_info ()
       fields[0] = build_lang_field_decl (FIELD_DECL, 
                     get_identifier ("match_function"), ptr_type_node);
       fields[1] = build_lang_field_decl (FIELD_DECL, 
-                    get_identifier ("coerced_value"), ptr_type_node);
-      fields[2] = build_lang_field_decl (FIELD_DECL, 
                     get_identifier ("language"), short_integer_type_node);
-      fields[3] = build_lang_field_decl (FIELD_DECL, 
+      fields[2] = build_lang_field_decl (FIELD_DECL, 
                     get_identifier ("version"), short_integer_type_node);
       /* N.B.: The fourth field LEN is expected to be
         the number of fields - 1, not the total number of fields.  */
-      finish_builtin_type (t1, "__eh_info", fields, 3, ptr_type_node);
+      finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node);
       t = make_lang_type (RECORD_TYPE);
       fields[0] = build_lang_field_decl (FIELD_DECL, 
                                               get_identifier ("eh_info"), t1);
@@ -414,6 +415,48 @@ build_eh_type_type (type)
   return build1 (ADDR_EXPR, ptr_type_node, exp);
 }
 
+/* Build the address of a runtime type for use in the runtime matching
+   field of the new exception model */
+
+static tree
+build_eh_type_type_ref (type)
+     tree type;
+{
+  char *typestring;
+  tree exp;
+  int susp;
+
+  if (type == error_mark_node)
+    return error_mark_node;
+
+  /* peel back references, so they match.  */
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    type = TREE_TYPE (type);
+
+  /* Peel off cv qualifiers.  */
+  type = TYPE_MAIN_VARIANT (type);
+
+  push_obstacks_nochange ();
+  end_temporary_allocation ();
+
+  if (flag_rtti)
+    {
+      exp = get_tinfo_fn (type);
+      TREE_USED (exp) = 1;
+      mark_inline_for_output (exp);
+      exp = build1 (ADDR_EXPR, ptr_type_node, exp);
+    }
+  else
+    {
+      typestring = build_overload_name (type, 1, 1);
+      exp = combine_strings (build_string (strlen (typestring)+1, typestring));
+      exp = build1 (ADDR_EXPR, ptr_type_node, exp);
+    }
+  pop_obstacks ();
+  return (exp);
+}
+
+
 /* Build a type value for use at runtime for a exp that is thrown or
    matched against by the exception handling system.  */
 
@@ -495,7 +538,7 @@ build_terminate_handler ()
   return term;
 }
 
-/* call this to start a catch block. Typename is the typename, and identifier
+/* Call this to start a catch block. Typename is the typename, and identifier
    is the variable to place the object in or NULL if the variable doesn't
    matter.  If typename is NULL, that means its a "catch (...)" or catch
    everything.  In that case we don't need to do any type checking.
@@ -505,9 +548,7 @@ void
 expand_start_catch_block (declspecs, declarator)
      tree declspecs, declarator;
 {
-  rtx false_label_rtx;
-  tree decl = NULL_TREE;
-  tree init;
+  tree decl;
 
   if (processing_template_decl)
     {
@@ -527,6 +568,25 @@ expand_start_catch_block (declspecs, declarator)
   if (! doing_eh (1))
     return;
 
+  if (flag_new_exceptions)
+    process_start_catch_block (declspecs, declarator);
+  else
+    process_start_catch_block_old (declspecs, declarator);
+}
+
+
+/* This function performs the expand_start_catch_block functionality for 
+   exceptions implemented in the old style, where catch blocks were all
+   called, and had to check the runtime information themselves. */
+
+static void 
+process_start_catch_block_old (declspecs, declarator)
+     tree declspecs, declarator;
+{
+  rtx false_label_rtx;
+  tree decl = NULL_TREE;
+  tree init;
+
   /* Create a binding level for the eh_info and the exception object
      cleanup.  */
   pushlevel (0);
@@ -631,6 +691,111 @@ expand_start_catch_block (declspecs, declarator)
   emit_line_note (input_filename, lineno);
 }
 
+/* This function performs the expand_start_catch_block functionality for 
+   exceptions implemented in the new style. __throw determines whether
+   a handler needs to be called or not, so the handler itself has to do
+   nothing additionaal. */
+
+static void 
+process_start_catch_block (declspecs, declarator)
+     tree declspecs, declarator;
+{
+  rtx false_label_rtx;
+  tree decl = NULL_TREE;
+  tree init;
+
+  /* Create a binding level for the eh_info and the exception object
+     cleanup.  */
+  pushlevel (0);
+  expand_start_bindings (0);
+
+
+  if (declspecs)
+    {
+      decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
+
+      if (decl == NULL_TREE)
+       error ("invalid catch parameter");
+    }
+
+  if (decl)
+    start_catch_handler (build_eh_type_type_ref (TREE_TYPE (decl)));
+  else
+    start_catch_handler (NULL_TREE);
+
+  emit_line_note (input_filename, lineno);
+
+  push_eh_info ();
+
+  if (decl)
+    {
+      tree exp;
+      rtx call_rtx, return_value_rtx;
+      tree init_type;
+
+      /* Make sure we mark the catch param as used, otherwise we'll get
+        a warning about an unused ((anonymous)).  */
+      TREE_USED (decl) = 1;
+
+      /* Figure out the type that the initializer is.  */
+      init_type = TREE_TYPE (decl);
+      if (TREE_CODE (init_type) != REFERENCE_TYPE
+         && TREE_CODE (init_type) != POINTER_TYPE)
+       init_type = build_reference_type (init_type);
+
+      exp = get_eh_value ();
+
+      /* Since pointers are passed by value, initialize a reference to
+        pointer catch parm with the address of the value slot.  */
+      if (TREE_CODE (init_type) == REFERENCE_TYPE
+         && TREE_CODE (TREE_TYPE (init_type)) == POINTER_TYPE)
+       exp = build_unary_op (ADDR_EXPR, exp, 1);
+
+      exp = ocp_convert (init_type , exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
+
+      push_eh_cleanup ();
+
+      /* Create a binding level for the parm.  */
+      pushlevel (0);
+      expand_start_bindings (0);
+
+      init = convert_from_reference (exp);
+
+      /* If the constructor for the catch parm exits via an exception, we
+         must call terminate.  See eh23.C.  */
+      if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+       {
+         /* Generate the copy constructor call directly so we can wrap it.
+            See also expand_default_init.  */
+         init = ocp_convert (TREE_TYPE (decl), init,
+                             CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
+         init = build (TRY_CATCH_EXPR, TREE_TYPE (init), init,
+                       build_terminate_handler ());
+       }
+
+      /* Let `cp_finish_decl' know that this initializer is ok.  */
+      DECL_INITIAL (decl) = init;
+      decl = pushdecl (decl);
+
+      cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
+    }
+  else
+    {
+      push_eh_cleanup ();
+
+      /* Create a binding level for the parm.  */
+      pushlevel (0);
+      expand_start_bindings (0);
+
+      /* Fall into the catch all section.  */
+    }
+
+  init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node);
+  expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  emit_line_note (input_filename, lineno);
+}
+
 
 
 /* Call this to end a catch block.  Its responsible for emitting the
@@ -658,7 +823,8 @@ expand_end_catch_block ()
 
   /* label we emit to jump to if this catch block didn't match.  */
   /* This the closing } in the `if (eq) {' of the documentation.  */
-  emit_label (pop_label_entry (&false_label_stack));
+  if (! flag_new_exceptions)
+    emit_label (pop_label_entry (&false_label_stack));
 }
 
 /* An exception spec is implemented more or less like:
@@ -686,7 +852,6 @@ expand_end_eh_spec (raises)
   int count = 0;
 
   expand_start_all_catch ();
-  start_catch_handler (NULL);
   expand_start_catch_block (NULL_TREE, NULL_TREE);
 
   /* Build up an array of type_infos.  */
index b081fa7..cad7304 100644 (file)
@@ -93,6 +93,7 @@ struct cp_eh_info
   bool caught;
   cp_eh_info *next;
   long handlers;
+  void *original_value;
 };
 
 /* Language-specific EH info pointer, defined in libgcc2. */
@@ -162,7 +163,10 @@ __cplus_type_matcher (cp_eh_info *info, exception_table *matching_info,
   /* we don't worry about version info yet, there is only one version! */
   
   void *match_type = ((rtimetype) (matching_info->match_info)) ();
-  ret = __throw_type_match_rtti (match_type, info->type, info->value);
+  ret = __throw_type_match_rtti (match_type, info->type, info->original_value);
+  /* change value of exception */
+  if (ret)
+    info->value = ret;
   return ret;
 }
 
@@ -180,11 +184,11 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
   p->cleanup = cleanup;
   p->handlers = 0;
   p->caught = false;
+  p->original_value = value;
 
   p->eh_info.match_function = __cplus_type_matcher;
   p->eh_info.language = EH_LANG_C_plus_plus;
   p->eh_info.version = 1;
-  p->eh_info.coerced_value = NULL;
 
   cp_eh_info **q = __get_eh_info ();
 
index b3b408c..ffc45e6 100644 (file)
@@ -3253,7 +3253,6 @@ function_try_block:
          ctor_initializer_opt compstmt
                { 
                   expand_start_all_catch (); 
-                  start_catch_handler (NULL);
                 }
          handler_seq
                {
index 60c4c32..763f208 100644 (file)
@@ -589,7 +589,6 @@ finish_try_block (try_block)
   else
     {
       expand_start_all_catch ();  
-      start_catch_handler (NULL);
     }
 }
 
index c16d66a..c8d98c0 100644 (file)
@@ -92,7 +92,6 @@ typedef void * (*__eh_matcher)          PROTO ((void *, void *, void *));
 typedef struct __eh_info 
 {
   __eh_matcher match_function;
-  void *coerced_value;
   short language;
   short version;
 } __eh_info;
index 63d6c82..6ffa920 100644 (file)
@@ -1025,7 +1025,7 @@ get_dynamic_handler_chain ()
 
   /* This is the offset of dynamic_handler_chain in the eh_context struct
      declared in eh-common.h. If its location is change, change this offset */
-  dhc = plus_constant (ehc, GET_MODE_SIZE (Pmode));
+  dhc = plus_constant (ehc, POINTER_SIZE / BITS_PER_UNIT);
 
   result = copy_to_reg (dhc);
 
@@ -1045,7 +1045,7 @@ get_dynamic_cleanup_chain ()
   rtx dhc, dcc, result;
 
   dhc = get_dynamic_handler_chain ();
-  dcc = plus_constant (dhc, GET_MODE_SIZE (Pmode));
+  dcc = plus_constant (dhc, POINTER_SIZE / BITS_PER_UNIT);
 
   result = copy_to_reg (dcc);
 
@@ -1618,6 +1618,10 @@ expand_start_all_catch ()
       expand_eh_region_start ();
       ehstack.top->entry->outer_context = outer_context;
     }
+
+  /* We also have to start the handler if we aren't using the new model. */
+  if (! flag_new_exceptions)
+    start_catch_handler (NULL);
 }
 
 /* Finish up the catch block.  At this point all the insns for the
index 1fc703e..4e17faf 100644 (file)
@@ -3426,10 +3426,7 @@ find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
                     {
                       ret = (*matcher)(eh_info, &tab[pos], table);
                       if (ret)
-                        {
-                          ((__eh_info *)eh_info)->coerced_value = ret;
-                          return tab[pos].exception_handler;
-                        }
+                        return tab[pos].exception_handler;
                     }
                 }
               else