Fix defer when not calling recover in function with named results.
From-SVN: r178905
This commit is contained in:
parent
fae3f4598a
commit
b9f04a8461
8 changed files with 57 additions and 27 deletions
|
@ -13,7 +13,7 @@
|
|||
/* This function is called each time we need to defer a call. */
|
||||
|
||||
void
|
||||
__go_defer (void *frame, void (*pfn) (void *), void *arg)
|
||||
__go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
|
||||
{
|
||||
struct __go_defer_stack *n;
|
||||
|
||||
|
@ -34,7 +34,7 @@ __go_defer (void *frame, void (*pfn) (void *), void *arg)
|
|||
/* This function is called when we want to undefer the stack. */
|
||||
|
||||
void
|
||||
__go_undefer (void *frame)
|
||||
__go_undefer (_Bool *frame)
|
||||
{
|
||||
if (__go_panic_defer == NULL)
|
||||
return;
|
||||
|
@ -53,6 +53,12 @@ __go_undefer (void *frame)
|
|||
|
||||
__go_panic_defer->__defer = d->__next;
|
||||
__go_free (d);
|
||||
|
||||
/* Since we are executing a defer function here, we know we are
|
||||
returning from the calling function. If the calling
|
||||
function, or one of its callees, paniced, then the defer
|
||||
functions would be executed by __go_panic. */
|
||||
*frame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,10 @@ struct __go_defer_stack
|
|||
/* The next entry in the stack. */
|
||||
struct __go_defer_stack *__next;
|
||||
|
||||
/* The frame pointer for the function which called this defer
|
||||
statement. */
|
||||
void *__frame;
|
||||
/* The stack variable for the function which called this defer
|
||||
statement. This is set to 1 if we are returning from that
|
||||
function, 0 if we are panicing through it. */
|
||||
_Bool *__frame;
|
||||
|
||||
/* The value of the panic stack when this function is deferred.
|
||||
This function can not recover this value from the panic stack.
|
||||
|
|
|
@ -87,6 +87,12 @@ __go_panic (struct __go_empty_interface arg)
|
|||
/* __go_unwind_stack should not return. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Because we executed that defer function by a panic, and
|
||||
it did not call recover, we know that we are not
|
||||
returning from the calling function--we are panicing
|
||||
through it. */
|
||||
*d->__frame = 0;
|
||||
}
|
||||
|
||||
__go_panic_defer->__defer = d->__next;
|
||||
|
|
|
@ -44,7 +44,7 @@ static const _Unwind_Exception_Class __go_exception_class =
|
|||
continue unwinding. */
|
||||
|
||||
void
|
||||
__go_check_defer (void *frame)
|
||||
__go_check_defer (_Bool *frame)
|
||||
{
|
||||
struct _Unwind_Exception *hdr;
|
||||
|
||||
|
@ -103,8 +103,12 @@ __go_check_defer (void *frame)
|
|||
if (was_recovered)
|
||||
{
|
||||
/* Just return and continue executing Go code. */
|
||||
*frame = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We are panicing through this function. */
|
||||
*frame = 0;
|
||||
}
|
||||
else if (__go_panic_defer->__defer != NULL
|
||||
&& __go_panic_defer->__defer->__pfn == NULL
|
||||
|
@ -118,6 +122,10 @@ __go_check_defer (void *frame)
|
|||
d = __go_panic_defer->__defer;
|
||||
__go_panic_defer->__defer = d->__next;
|
||||
__go_free (d);
|
||||
|
||||
/* We are returning from this function. */
|
||||
*frame = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue