exception.cc (__cplus_type_matcher): Call __throw_type_match_rtti_2.
authorJason Merrill <jason@yorick.cygnus.com>
Tue, 24 Aug 1999 04:16:06 +0000 (04:16 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 24 Aug 1999 04:16:06 +0000 (00:16 -0400)
* exception.cc (__cplus_type_matcher): Call __throw_type_match_rtti_2.
Return arbitrary pointer or NULL.
(check_eh_spec): Call __throw_type_match_rtti_2.
* tinfo.h (*::dcast): Return int.  Add valp parm.
* tinfo.cc (*::dcast): Likewise.  Adjust to allow for null pointers.
* tinfo2.cc (__throw_type_match_rtti_2): Likewise.
(__throw_type_match_rtti): Now just a wrapper.

* except.c: Lose CatchMatch, FirstExceptionMatch, and Unwind.
(init_exception_processing): Don't initialize them.

From-SVN: r28811

gcc/cp/ChangeLog
gcc/cp/except.c
gcc/cp/exception.cc
gcc/cp/tinfo.cc
gcc/cp/tinfo.h
gcc/cp/tinfo2.cc

index 3f279000acaa9f4a33a61e0a55fb8182c86a96ed..77deef6d25bfc3f1e921195395d6b35496cd4862 100644 (file)
@@ -1,3 +1,16 @@
+1999-08-23  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * exception.cc (__cplus_type_matcher): Call __throw_type_match_rtti_2.
+       Return arbitrary pointer or NULL.
+       (check_eh_spec): Call __throw_type_match_rtti_2.
+       * tinfo.h (*::dcast): Return int.  Add valp parm.
+       * tinfo.cc (*::dcast): Likewise.  Adjust to allow for null pointers.
+       * tinfo2.cc (__throw_type_match_rtti_2): Likewise.
+       (__throw_type_match_rtti): Now just a wrapper.
+
+       * except.c: Lose CatchMatch, FirstExceptionMatch, and Unwind.
+       (init_exception_processing): Don't initialize them.
+
 1999-08-23  Paul Burchard <burchard@pobox.com>
 
        * decl.c (check_default_argument): Fix typo.
index 0a9bcf54f0fec253d33c1dd0c91003bae03b1715..100ff2c7b88e8404a10485f167e0257748de3c7b 100644 (file)
@@ -155,25 +155,12 @@ asm (TEXT_SECTION_ASM_OP);
 /* local globals for function calls
    ====================================================================== */
 
-/* Used to cache "terminate" and "__throw_type_match*".  */
-static tree Terminate, CatchMatch;
-
-/* Used to cache __find_first_exception_table_match for throw.  */
-static tree FirstExceptionMatch;
-
-/* Used to cache a call to __unwind_function.  */
-static tree Unwind;
+static tree Terminate;
 
 /* ====================================================================== */
 
-
-/* ========================================================================= */
-
 /* sets up all the global eh stuff that needs to be initialized at the
-   start of compilation.
-
-   This includes:
-               - Setting up all the function call trees.  */
+   start of compilation.  */
 
 void
 init_exception_processing ()
@@ -189,36 +176,9 @@ init_exception_processing ()
   if (flag_honor_std)
     pop_namespace ();
 
-  push_lang_context (lang_name_c);
-
   set_exception_lang_code (EH_LANG_C_plus_plus);
   set_exception_version_code (1);
 
-  CatchMatch
-    = builtin_function (flag_rtti
-                       ? "__throw_type_match_rtti"
-                       : "__throw_type_match",
-                       build_function_type (ptr_type_node,
-                                            tree_cons (NULL_TREE, const_ptr_type_node,
-                                                       tree_cons (NULL_TREE, const_ptr_type_node,
-                                                                  tree_cons (NULL_TREE, ptr_type_node,
-                                                                             void_list_node)))),
-                       NOT_BUILT_IN, NULL_PTR);
-  FirstExceptionMatch
-    = builtin_function ("__find_first_exception_table_match",
-                       build_function_type (ptr_type_node,
-                                            tree_cons (NULL_TREE, ptr_type_node,
-                                                       void_list_node)),
-                       NOT_BUILT_IN, NULL_PTR);
-  Unwind
-    = builtin_function ("__unwind_function",
-                       build_function_type (void_type_node,
-                                            tree_cons (NULL_TREE, ptr_type_node,
-                                                       void_list_node)),
-                       NOT_BUILT_IN, NULL_PTR);
-
-  pop_lang_context ();
-
   /* If we use setjmp/longjmp EH, arrange for all cleanup actions to
      be protected with __terminate.  */
   protect_cleanup_actions_with_terminate = 1;
index 372536ed9520f782861674a02fe79e8526ce69b0..efc0b1fe83c315ef924906cbe67c718f47aca0e7 100644 (file)
@@ -165,12 +165,14 @@ __eh_free (void *p)
   free (p);
 }
 
+extern "C" int __throw_type_match_rtti_2 (const void *, const void *,
+                                        void *, void **);
+
 extern "C" void *
 __cplus_type_matcher (__eh_info *info_, void *match_info,
-                                 exception_descriptor *exception_table)
+                     exception_descriptor *exception_table)
 {
   cp_eh_info *info = (cp_eh_info *)info_;
-  void *ret;
 
   /* No exception table implies the old style mechanism, so don't check. */
   if (exception_table != NULL 
@@ -178,18 +180,19 @@ __cplus_type_matcher (__eh_info *info_, void *match_info,
     return NULL;
 
   if (match_info == CATCH_ALL_TYPE)
-    return info->value;
+    return (void *)1;
 
   /* we don't worry about version info yet, there is only one version! */
   
   void *match_type = ((void *(*)())match_info) ();
-  ret = __throw_type_match_rtti (match_type, info->type, info->original_value);
-  /* change value of exception */
-  if (ret)
-    info->value = ret;
-  return ret;
-}
 
+  if (__throw_type_match_rtti_2 (match_type, info->type,
+                                info->original_value, &info->value))
+    // Arbitrary non-null pointer.
+    return (void *)1;
+  else
+    return NULL;
+}
 
 /* Compiler hook to push a new exception onto the stack.
    Used by expand_throw().  */
@@ -278,10 +281,11 @@ extern "C" void
 __check_eh_spec (int n, const void **spec)
 {
   cp_eh_info *p = CP_EH_INFO;
+  void *d;
 
   for (int i = 0; i < n; ++i)
     {
-      if (__throw_type_match_rtti (spec[i], p->type, p->value))
+      if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
        throw;
     }
 
@@ -297,7 +301,7 @@ __check_eh_spec (int n, const void **spec)
          p = __exception_info;
          for (int i = 0; i < n; ++i)
            {
-             if (__throw_type_match_rtti (spec[i], p->type, p->value))
+             if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
                throw;
            }
        }
@@ -305,7 +309,7 @@ __check_eh_spec (int n, const void **spec)
       const std::type_info &bad_exc = typeid (std::bad_exception);
       for (int i = 0; i < n; ++i)
        {
-         if (__throw_type_match_rtti (spec[i], &bad_exc, p->value))
+         if (__throw_type_match_rtti_2 (spec[i], &bad_exc, p->value, &d))
            throw std::bad_exception ();
        }
 
index 5269cb5940e477b63974ac0493a098bef2d9c110..fe22e8de0745c0d6e3b9f0ffc186f159845a5036 100644 (file)
@@ -1,5 +1,5 @@
 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
-// Copyright (C) 1994, 1996, 1998 Free Software Foundation
+// Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation
 
 // This file is part of GNU CC.
 
@@ -63,43 +63,66 @@ __rtti_user (void *addr, const char *name)
 { new (addr) __user_type_info (name); }
 
 // dynamic_cast helper methods.
-// Returns a pointer to the desired sub-object or 0.
+// Returns 1 if the cast succeeds, 0 otherwise.  Stores the adjusted value
+// in VALP.
 
-void * __user_type_info::
-dcast (const type_info& to, int, void *addr, const type_info *, void *) const
-{ return (*this == to) ? addr : 0; }
+int __user_type_info::
+dcast (const type_info& to, int, void *addr, void **valp,
+       const type_info *, void *) const
+{
+  *valp = addr;
+  return (*this == to);
+}
 
-void * __si_type_info::
-dcast (const type_info& to, int require_public, void *addr,
+int __si_type_info::
+dcast (const type_info& to, int require_public, void *addr, void **valp,
        const type_info *sub, void *subptr) const
 {
   if (*this == to)
-    return addr;
-  return base.dcast (to, require_public, addr, sub, subptr);
+    {
+      *valp = addr;
+      return 1;
+    }
+  return base.dcast (to, require_public, addr, valp, sub, subptr);
 }
 
-void* __class_type_info::
-dcast (const type_info& desired, int is_public, void *objptr,
+int __class_type_info::
+dcast (const type_info& desired, int is_public, void *objptr, void **valp,
        const type_info *sub, void *subptr) const
 {
+  *valp = objptr;
+
   if (*this == desired)
-    return objptr;
+    return 1;
+
+  int match_found = 0;
+  void *match = 0;
 
-  void *match_found = 0;
   for (size_t i = 0; i < n_bases; i++)
     {
       if (is_public && base_list[i].access != PUBLIC)
        continue;
 
-      void *p = (char *)objptr + base_list[i].offset;
-      if (base_list[i].is_virtual)
-       p = *(void **)p;
-      p = base_list[i].base->dcast (desired, is_public, p, sub, subptr);
-      if (p)
+      void *p;
+
+      if (objptr)
        {
-         if (match_found == 0)
-           match_found = p;
-         else if (match_found != p)
+         p = (char *)objptr + base_list[i].offset;
+         if (base_list[i].is_virtual)
+           p = *(void **)p;
+       }
+      else
+       /* Preserve null pointer.  */
+       p = objptr;
+
+      if (base_list[i].base->dcast (desired, is_public, p, &p, sub, subptr))
+       {
+         if (! match_found)
+           {
+             match_found = 1;
+             match = p;
+           }
+         else if (match != p)
            {
              if (sub)
                {
@@ -109,26 +132,30 @@ dcast (const type_info& desired, int is_public, void *objptr,
                  const __user_type_info &d =
                    static_cast <const __user_type_info &> (desired);
 
-                 void *os = d.dcast (*sub, 1, match_found);
-                 void *ns = d.dcast (*sub, 1, p);
+                 void *os;
+                 d.dcast (*sub, 1, match, &os);
+                 void *ns;
+                 d.dcast (*sub, 1, p, &ns);
 
                  if (os == ns)
-                   /* ambiguous -- subptr is a virtual base */;
+                   // Both have the same subobject, so we can't disambiguate;
+                   // i.e. subptr is a virtual base.
+                   return 0;
                  else if (os == subptr)
                    continue;
                  else if (ns == subptr)
                    {
-                     match_found = p;
+                     match = p;
                      continue;
                    }
                }
-
-             // base found at two different pointers,
-             // conversion is not unique
-             return 0;
+             else
+               // We're not downcasting, so we can't disambiguate.
+               return 0;
            }
        }
     }
 
+  *valp = match;
   return match_found;
 }
index e0b9eec7897075db0755f09a6a8cf49ab9070bef..ffca9c35cf16940173391ef664418445bb7cebbc 100644 (file)
@@ -1,5 +1,5 @@
 // RTTI support internals for -*- C++ -*-
-// Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation
+// Copyright (C) 1994, 1995, 1996, 1998, 1999 Free Software Foundation
 
 #include "typeinfo"
 
@@ -12,8 +12,8 @@ struct __user_type_info : public std::type_info {
 
   // If our type can be converted to the desired type, 
   // return the pointer, adjusted accordingly; else return 0.
-  virtual void* dcast (const type_info &, int, void *,
-                      const type_info * = 0, void * = 0) const;
+  virtual int dcast (const type_info &, int, void *, void **,
+                    const type_info * = 0, void * = 0) const;
 };
 
 // type_info for a class with one public, nonvirtual base class.
@@ -25,8 +25,8 @@ public:
   __si_type_info (const char *n, const __user_type_info &b)
     : __user_type_info (n), base (b) { }
 
-  virtual void *dcast (const type_info &, int, void *,
-                      const type_info * = 0, void * = 0) const;
+  virtual int dcast (const type_info &, int, void *, void **,
+                    const type_info * = 0, void * = 0) const;
 };
 
 // type_info for a general class.
@@ -50,6 +50,6 @@ struct __class_type_info : public __user_type_info {
     : __user_type_info (name), base_list (bl), n_bases (bn) {}
 
   // This is a little complex.
-  virtual void* dcast (const type_info &, int, void *,
-                      const type_info * = 0, void * = 0) const;
+  virtual int dcast (const type_info &, int, void *, void **,
+                    const type_info * = 0, void * = 0) const;
 };
index b101db3c05483b0f42549cc67a6d4d4da8d5d222..877872f4e70a6a450e11cbabe81115c97e97a1af 100644 (file)
@@ -1,5 +1,5 @@
 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
-// Copyright (C) 1994, 96-97, 1998 Free Software Foundation
+// Copyright (C) 1994, 96-97, 1998, 1999 Free Software Foundation
 
 // This file is part of GNU CC.
 
@@ -93,28 +93,23 @@ struct __array_type_info : public type_info {
 /* Low level match routine used by compiler to match types of catch
    variables and thrown objects.  */
 
-extern "C" void*
-__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
-                        void *objptr)
+extern "C" int
+__throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
+                        void *objptr, void **valp)
 {
   const type_info &catch_type = *(const type_info *)catch_type_r;
   const type_info &throw_type = *(const type_info *)throw_type_r;
-  
-  if (catch_type == throw_type)
-    return objptr;
-  
-#if 0
-  printf ("We want to match a %s against a %s!\n",
-         throw_type.name (), catch_type.name ());
-#endif
 
-  void *new_objptr = 0;
+  *valp = objptr;
 
+  if (catch_type == throw_type)
+    return 1;
+  
   if (const __user_type_info *p
       = dynamic_cast <const __user_type_info *> (&throw_type))
     {
       /* The 1 skips conversions to private bases. */
-      new_objptr = p->dcast (catch_type, 1, objptr);
+      return p->dcast (catch_type, 1, objptr, valp);
     }
   else if (const __pointer_type_info *fr =
           dynamic_cast <const __pointer_type_info *> (&throw_type))
@@ -123,7 +118,7 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
           dynamic_cast <const __pointer_type_info *> (&catch_type);
 
       if (! to)
-       goto fail;
+       return 0;
 
       const type_info *subfr = &fr->type, *subto = &to->type;
       __attr_type_info::cv cvfrom, cvto;
@@ -150,18 +145,18 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
           > (cvto & __attr_type_info::CONST))
          || ((cvfrom & __attr_type_info::VOLATILE)
              > (cvto & __attr_type_info::VOLATILE)))
-       goto fail;
+       return 0;
 
       if (*subto == *subfr)
-       new_objptr = objptr;
+       return 1;
       else if (*subto == typeid (void)
               && dynamic_cast <const __func_type_info *> (subfr) == 0)
-       new_objptr = objptr;
+       return 1;
       else if (const __user_type_info *p
               = dynamic_cast <const __user_type_info *> (subfr))
        {
          /* The 1 skips conversions to private bases. */
-         new_objptr = p->dcast (*subto, 1, objptr);
+         return p->dcast (*subto, 1, objptr, valp);
        }
       else if (const __pointer_type_info *pfr
               = dynamic_cast <const __pointer_type_info *> (subfr))
@@ -172,7 +167,7 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
            = dynamic_cast <const __pointer_type_info *> (subto);
 
          if (! pto)
-           goto fail;
+           return 0;
            
          bool constp = (cvto & __attr_type_info::CONST);
          for (subto = &pto->type, subfr = &pfr->type; ;
@@ -200,38 +195,42 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
                   > (cvto & __attr_type_info::CONST))
                  || ((cvfrom & __attr_type_info::VOLATILE)
                      > (cvto & __attr_type_info::VOLATILE)))
-               goto fail;
+               return 0;
 
              if (! constp
                  && (((cvfrom & __attr_type_info::CONST)
                       < (cvto & __attr_type_info::CONST))
                      || ((cvfrom & __attr_type_info::VOLATILE)
                          < (cvto & __attr_type_info::VOLATILE))))
-               goto fail;
+               return 0;
 
              if (*subto == *subfr)
-               {
-                 new_objptr = objptr;
-                 break;
-               }
+               return 1;
 
              pto = dynamic_cast <const __pointer_type_info *> (subto);
              pfr = dynamic_cast <const __pointer_type_info *> (subfr);
              if (! pto || ! pfr)
-               goto fail;              
+               return 0;               
 
              if (! (cvto & __attr_type_info::CONST))
                constp = false;
            }
        }
     }
- fail:
 
-#if 0
-  if (new_objptr)
-    printf ("It converts, delta is %d\n", new_objptr-objptr);
-#endif
-  return new_objptr;
+  return 0;
+}
+
+/* Backward compatibility wrapper.  */
+
+extern "C" void*
+__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
+                        void *objptr)
+{
+  void *ret;
+  if (__throw_type_match_rtti_2 (catch_type_r, throw_type_r, objptr, &ret))
+    return ret;
+  return NULL;
 }
 
 /* Called from __cp_pop_exception.  Is P the type_info node for a pointer
@@ -278,8 +277,11 @@ __dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
                int require_public, void *address,
                const type_info & (*sub)(void), void *subptr)
 {
-  return static_cast <const __user_type_info &> (from ()).dcast
-    (to (), require_public, address, &(sub ()), subptr);
+  void *ret;
+  if (static_cast <const __user_type_info &> (from ()).dcast
+      (to (), require_public, address, &ret, &(sub ()), subptr))
+    return ret;
+  return 0;
 }
 
 // type_info nodes and functions for the builtin types.  The mangling here