]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: better dclcontext handling in func{hdr,body}
authorMatthew Dempsky <mdempsky@google.com>
Mon, 14 Sep 2020 19:53:36 +0000 (12:53 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 14 Sep 2020 23:42:35 +0000 (23:42 +0000)
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 <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/main.go

index 69eb13f60764992acd56101b35d7b03d5b3f47d8..a362d1a643bef090d066ffee1091c5e5e95e2d43 100644 (file)
@@ -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.
index eedfc4bb259647855f68d3986d68e77db82a05b2..9bce6cf8cb461ef715596a99065bdfcf86ca4c47 100644 (file)
@@ -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))
        }