aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1999-08-24 04:16:06 +0000
committerJason Merrill <jason@gcc.gnu.org>1999-08-24 00:16:06 -0400
commitbbd0d54ab38bcf23ec5aef1d50c2593d6c39853a (patch)
treec097dc69150c566739513cb37b500b1e01cdb7b0 /gcc
parent657ac7664ccb23e3d8c45ca4932a6226fef076de (diff)
downloadgcc-bbd0d54ab38bcf23ec5aef1d50c2593d6c39853a.zip
gcc-bbd0d54ab38bcf23ec5aef1d50c2593d6c39853a.tar.gz
gcc-bbd0d54ab38bcf23ec5aef1d50c2593d6c39853a.tar.bz2
exception.cc (__cplus_type_matcher): Call __throw_type_match_rtti_2.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/except.c44
-rw-r--r--gcc/cp/exception.cc28
-rw-r--r--gcc/cp/tinfo.cc85
-rw-r--r--gcc/cp/tinfo.h14
-rw-r--r--gcc/cp/tinfo2.cc72
6 files changed, 131 insertions, 125 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3f27900..77deef6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 0a9bcf5..100ff2c 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -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;
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
index 372536e..efc0b1f 100644
--- a/gcc/cp/exception.cc
+++ b/gcc/cp/exception.cc
@@ -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 ();
}
diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc
index 5269cb5..fe22e8d 100644
--- a/gcc/cp/tinfo.cc
+++ b/gcc/cp/tinfo.cc
@@ -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;
}
diff --git a/gcc/cp/tinfo.h b/gcc/cp/tinfo.h
index e0b9eec..ffca9c3 100644
--- a/gcc/cp/tinfo.h
+++ b/gcc/cp/tinfo.h
@@ -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;
};
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc
index b101db3..877872f 100644
--- a/gcc/cp/tinfo2.cc
+++ b/gcc/cp/tinfo2.cc
@@ -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