mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 20:07:23 +08:00
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:
parent
657ac7664c
commit
bbd0d54ab3
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user