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
This commit is contained in:
Jason Merrill 1999-08-24 04:16:06 +00:00 committed by Jason Merrill
parent 657ac7664c
commit bbd0d54ab3
6 changed files with 132 additions and 126 deletions

View 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.

View 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;

View 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 ();
}

View 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
{
if (*this == desired)
return objptr;
*valp = objptr;
if (*this == desired)
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;
}

View 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;
};

View 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;
*valp = objptr;
if (catch_type == throw_type)
return objptr;
return 1;
#if 0
printf ("We want to match a %s against a %s!\n",
throw_type.name (), catch_type.name ());
#endif
void *new_objptr = 0;
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