aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/gc/pgen.c7
-rw-r--r--src/pkg/runtime/panic.c10
2 files changed, 10 insertions, 7 deletions
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index 2850af6bb0..2d364529e0 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -168,8 +168,13 @@ compile(Node *fn)
if(retpc)
patch(retpc, pc);
ginit();
- if(hasdefer)
+ if(hasdefer) {
ginscall(deferreturn, 0);
+ // deferreturn pretends to have one uintptr argument.
+ // Reserve space for it so stack scanner is happy.
+ if(maxarg < widthptr)
+ maxarg = widthptr;
+ }
if(curfn->exit)
genlist(curfn->exit);
gclean();
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c
index 8227a444d3..b60547ea10 100644
--- a/src/pkg/runtime/panic.c
+++ b/src/pkg/runtime/panic.c
@@ -157,14 +157,12 @@ runtimeĀ·deferproc(int32 siz, FuncVal *fn, ...)
// is called again and again until there are no more deferred functions.
// Cannot split the stack because we reuse the caller's frame to
// call the deferred function.
-//
-// The ... in the prototype keeps the compiler from declaring
-// an argument frame size. deferreturn is a very special function,
-// and if the runtime ever asks for its frame size, that means
-// the traceback routines are probably broken.
+
+// The single argument isn't actually used - it just has its address
+// taken so it can be matched against pending defers.
#pragma textflag NOSPLIT
void
-runtimeĀ·deferreturn(uintptr arg0, ...)
+runtimeĀ·deferreturn(uintptr arg0)
{
Defer *d;
byte *argp;