From 237410547bb81ae3c58e9c5bf0cf59edc989e243 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Mon, 14 Sep 2020 12:53:36 -0700 Subject: [PATCH] cmd/compile: better dclcontext handling in func{hdr,body} funchdr and funcbody currently assume that either (1) Curfn == nil && dclcontext == PEXTERN, or (2) Curfn != nil && dclcontext == PAUTO. This is a reasonable assumption during parsing. However, these functions end up getting used in other contexts, and not all callers are so disciplined about Curfn/dclcontext handling. This CL changes them to save/restore arbitrary Curfn/dclcontext pairs instead. This is necessary for the followup CL, which pushes fninit earlier. Otherwise, Curfn/dclcontext fall out of sync, and funchdr panics. Passes toolstash-check. Updates #33485. Change-Id: I19b1be23db1bad6475345ae5c81bbdc66291a3a7 Reviewed-on: https://go-review.googlesource.com/c/go/+/254838 Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Keith Randall Trust: Matthew Dempsky --- src/cmd/compile/internal/gc/dcl.go | 28 +++++++++++++--------------- src/cmd/compile/internal/gc/main.go | 3 +++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 69eb13f607..a362d1a643 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -382,14 +382,11 @@ func ifacedcl(n *Node) { // returns in auto-declaration context. func funchdr(n *Node) { // change the declaration context from extern to auto - if Curfn == nil && dclcontext != PEXTERN { - Fatalf("funchdr: dclcontext = %d", dclcontext) - } - + funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext}) + Curfn = n dclcontext = PAUTO + types.Markdcl() - funcstack = append(funcstack, Curfn) - Curfn = n if n.Func.Nname != nil { funcargs(n.Func.Nname.Name.Param.Ntype) @@ -497,21 +494,22 @@ func funcarg2(f *types.Field, ctxt Class) { declare(n, ctxt) } -var funcstack []*Node // stack of previous values of Curfn +var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext + +type funcStackEnt struct { + curfn *Node + dclcontext Class +} // finish the body. // called in auto-declaration context. // returns in extern-declaration context. func funcbody() { - // change the declaration context from auto to extern - if dclcontext != PAUTO { - Fatalf("funcbody: unexpected dclcontext %d", dclcontext) - } + // change the declaration context from auto to previous context types.Popdcl() - funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1] - if Curfn == nil { - dclcontext = PEXTERN - } + var e funcStackEnt + funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1] + Curfn, dclcontext = e.curfn, e.dclcontext } // structs, functions, and methods. diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index eedfc4bb25..9bce6cf8cb 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -809,6 +809,9 @@ func Main(archInit func(*Arch)) { } } + if len(funcStack) != 0 { + Fatalf("funcStack is non-empty: %v", len(funcStack)) + } if len(compilequeue) != 0 { Fatalf("%d uncompiled functions", len(compilequeue)) } -- 2.48.1