diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2011-06-29 14:18:48 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2011-06-29 14:18:48 +0000 |
commit | 3a86cfeb42e2a6bbbe6ecdbddacbf182a7db899a (patch) | |
tree | 8823824b74da8e60cbab15045913ea4c5340cfdd /gcc | |
parent | 7b37a0c548b633d91e07fbb2c941828aafd5cd3b (diff) | |
download | gcc-3a86cfeb42e2a6bbbe6ecdbddacbf182a7db899a.zip gcc-3a86cfeb42e2a6bbbe6ecdbddacbf182a7db899a.tar.gz gcc-3a86cfeb42e2a6bbbe6ecdbddacbf182a7db899a.tar.bz2 |
unwind-arm.c (enum __cxa_type_match_result): New.
gcc/
* config/arm/unwind-arm.c (enum __cxa_type_match_result): New.
(cxa_type_match): Correct declaration.
(__gnu_unwind_pr_common): Reconstruct
additional indirection when __cxa_type_match returns
succeeded_with_ptr_to_base.
libstdc++/
* libsupc++/eh_arm.c (__cxa_type_match): Construct address of
thrown object here. Return succeded_with_ptr_to_base for all
pointer cases.
From-SVN: r175641
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/arm/unwind-arm.c | 40 |
2 files changed, 38 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40ccb73..bfd8081 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-06-29 Nathan Sidwell <nathan@codesourcery.com> + + * config/arm/unwind-arm.c (enum __cxa_type_match_result): New. + (cxa_type_match): Correct declaration. + (__gnu_unwind_pr_common): Reconstruct + additional indirection when __cxa_type_match returns + succeeded_with_ptr_to_base. + 2011-06-29 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> PR rtl-optimization/49114 diff --git a/gcc/config/arm/unwind-arm.c b/gcc/config/arm/unwind-arm.c index 4a9e232..90d258d 100644 --- a/gcc/config/arm/unwind-arm.c +++ b/gcc/config/arm/unwind-arm.c @@ -32,13 +32,18 @@ extern void abort (void); typedef unsigned char bool; typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ +enum __cxa_type_match_result + { + ctm_failed = 0, + ctm_succeeded = 1, + ctm_succeeded_with_ptr_to_base = 2 + }; void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp); -bool __attribute__((weak)) __cxa_type_match(_Unwind_Control_Block *ucbp, - const type_info *rttip, - bool is_reference, - void **matched_object); +enum __cxa_type_match_result __attribute__((weak)) __cxa_type_match + (_Unwind_Control_Block *ucbp, const type_info *rttip, + bool is_reference, void **matched_object); _Unwind_Ptr __attribute__((weak)) __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *); @@ -1107,6 +1112,7 @@ __gnu_unwind_pr_common (_Unwind_State state, _uw rtti; bool is_reference = (data[0] & uint32_highbit) != 0; void *matched; + enum __cxa_type_match_result match_type; /* Check for no-throw areas. */ if (data[1] == (_uw) -2) @@ -1118,17 +1124,31 @@ __gnu_unwind_pr_common (_Unwind_State state, { /* Match a catch specification. */ rtti = _Unwind_decode_target2 ((_uw) &data[1]); - if (!__cxa_type_match (ucbp, (type_info *) rtti, - is_reference, - &matched)) - matched = (void *)0; + match_type = __cxa_type_match (ucbp, + (type_info *) rtti, + is_reference, + &matched); } + else + match_type = ctm_succeeded; - if (matched) + if (match_type) { ucbp->barrier_cache.sp = _Unwind_GetGR (context, R_SP); - ucbp->barrier_cache.bitpattern[0] = (_uw) matched; + // ctm_succeeded_with_ptr_to_base really + // means _c_t_m indirected the pointer + // object. We have to reconstruct the + // additional pointer layer by using a temporary. + if (match_type == ctm_succeeded_with_ptr_to_base) + { + ucbp->barrier_cache.bitpattern[2] + = (_uw) matched; + ucbp->barrier_cache.bitpattern[0] + = (_uw) &ucbp->barrier_cache.bitpattern[2]; + } + else + ucbp->barrier_cache.bitpattern[0] = (_uw) matched; ucbp->barrier_cache.bitpattern[1] = (_uw) data; return _URC_HANDLER_FOUND; } |