* unwind.inc (DESTROY_FRAME_STATE): New macro. (_Unwind_RaiseException_Phase2, _Unwind_RaiseException, _Unwind_ForcedUnwind_Phase2): Invoke DESTROY_FRAME_STATE. * config/ia64/unwind-ia64.c (uw_destroy_frame_state): New function. (DESTROY_FRAME_STATE): Define. (uw_init_context_1): Call uw_destroy_frame_state. Index: unwind.inc =================================================================== RCS file: /cvs/gcc/gcc/gcc/unwind.inc,v retrieving revision 1.6 diff -u -r1.6 unwind.inc --- unwind.inc 2001/09/19 23:58:10 1.6 +++ unwind.inc 2002/04/01 22:57:30 @@ -29,6 +29,10 @@ the first such frame here. Cleanup code will call back into _Unwind_Resume and we'll continue Phase 2 there. */ +#ifndef DESTROY_FRAME_STATE +# define DESTROY_FRAME_STATE(fs_ptr) /* By default, do nothing. */ +#endif + static _Unwind_Reason_Code _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc, struct _Unwind_Context *context) @@ -49,7 +53,10 @@ if (code != _URC_NO_REASON) /* Some error encountered. Usually the unwinder doesn't diagnose these and merely crashes. */ - return _URC_FATAL_PHASE2_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE2_ERROR; + } /* Unwind successful. Run the personality routine, if any. */ if (fs.personality) @@ -57,9 +64,15 @@ code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler, exc->exception_class, exc, context); if (code == _URC_INSTALL_CONTEXT) - break; + { + DESTROY_FRAME_STATE(&fs); + break; + } if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE2_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE2_ERROR; + } } /* Don't let us unwind past the handler context. */ @@ -67,12 +80,12 @@ abort (); uw_update_context (context, &fs); + DESTROY_FRAME_STATE(&fs); } return code; } - /* Raise an exception, passing along the given exception object. */ _Unwind_Reason_Code @@ -94,12 +107,18 @@ if (code == _URC_END_OF_STACK) /* Hit end of stack with no handler found. */ - return _URC_END_OF_STACK; + { + DESTROY_FRAME_STATE(&fs); + return _URC_END_OF_STACK; + } if (code != _URC_NO_REASON) /* Some error encountered. Ususally the unwinder doesn't diagnose these and merely crashes. */ - return _URC_FATAL_PHASE1_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE1_ERROR; + } /* Unwind successful. Run the personality routine, if any. */ if (fs.personality) @@ -107,12 +126,19 @@ code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class, exc, &cur_context); if (code == _URC_HANDLER_FOUND) - break; + { + DESTROY_FRAME_STATE(&fs); + break; + } else if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE1_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE1_ERROR; + } } uw_update_context (&cur_context, &fs); + DESTROY_FRAME_STATE(&fs); } /* Indicate to _Unwind_Resume and associated subroutines that this @@ -146,7 +172,10 @@ code = uw_frame_state_for (context, &fs); if (code != _URC_NO_REASON && code != _URC_END_OF_STACK) - return _URC_FATAL_PHASE2_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE2_ERROR; + } /* Unwind successful. */ action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE; @@ -155,24 +184,37 @@ stop_code = (*stop) (1, action, exc->exception_class, exc, context, stop_argument); if (stop_code != _URC_NO_REASON) - return _URC_FATAL_PHASE2_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE2_ERROR; + } /* Stop didn't want to do anything. Invoke the personality handler, if applicable, to run cleanups. */ if (code == _URC_END_OF_STACK) - break; + { + DESTROY_FRAME_STATE(&fs); + break; + } if (fs.personality) { code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE, exc->exception_class, exc, context); if (code == _URC_INSTALL_CONTEXT) - break; + { + DESTROY_FRAME_STATE(&fs); + break; + } if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE2_ERROR; + { + DESTROY_FRAME_STATE(&fs); + return _URC_FATAL_PHASE2_ERROR; + } } uw_update_context (context, &fs); + DESTROY_FRAME_STATE(&fs); } return code; Index: config/ia64/unwind-ia64.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/ia64/unwind-ia64.c,v retrieving revision 1.5.2.2 diff -u -r1.5.2.2 unwind-ia64.c --- unwind-ia64.c 2002/03/26 19:37:13 1.5.2.2 +++ unwind-ia64.c 2002/04/01 22:57:30 @@ -1787,6 +1787,23 @@ } } +static void +uw_destroy_frame_state(_Unwind_FrameState *fs) +{ + struct unw_labeled_state *ls, *next; + + /* free labeled register states & stack: */ + for (ls = fs -> labeled_states; ls; ls = next) + { + next = ls->next; + free_state_stack(&ls->saved_state); + free(ls); + } + free_state_stack(&(fs -> curr)); +} + +#define DESTROY_FRAME_STATE(fs_ptr) uw_destroy_frame_state(fs_ptr) + /* Fill in CONTEXT for top-of-stack. The only valid registers at this level will be the return address and the CFA. Note that CFA = SP+16. */ @@ -1823,6 +1840,7 @@ abort (); uw_update_context (context, &fs); + uw_destroy_frame_state(&fs); } /* Install (ie longjmp to) the contents of TARGET. */