mirror of
https://github.com/golang/go
synced 2024-11-17 23:54:51 -07:00
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 <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
506eb0a9b1
commit
237410547b
@ -382,14 +382,11 @@ func ifacedcl(n *Node) {
|
|||||||
// returns in auto-declaration context.
|
// returns in auto-declaration context.
|
||||||
func funchdr(n *Node) {
|
func funchdr(n *Node) {
|
||||||
// change the declaration context from extern to auto
|
// change the declaration context from extern to auto
|
||||||
if Curfn == nil && dclcontext != PEXTERN {
|
funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
|
||||||
Fatalf("funchdr: dclcontext = %d", dclcontext)
|
|
||||||
}
|
|
||||||
|
|
||||||
dclcontext = PAUTO
|
|
||||||
types.Markdcl()
|
|
||||||
funcstack = append(funcstack, Curfn)
|
|
||||||
Curfn = n
|
Curfn = n
|
||||||
|
dclcontext = PAUTO
|
||||||
|
|
||||||
|
types.Markdcl()
|
||||||
|
|
||||||
if n.Func.Nname != nil {
|
if n.Func.Nname != nil {
|
||||||
funcargs(n.Func.Nname.Name.Param.Ntype)
|
funcargs(n.Func.Nname.Name.Param.Ntype)
|
||||||
@ -497,21 +494,22 @@ func funcarg2(f *types.Field, ctxt Class) {
|
|||||||
declare(n, ctxt)
|
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.
|
// finish the body.
|
||||||
// called in auto-declaration context.
|
// called in auto-declaration context.
|
||||||
// returns in extern-declaration context.
|
// returns in extern-declaration context.
|
||||||
func funcbody() {
|
func funcbody() {
|
||||||
// change the declaration context from auto to extern
|
// change the declaration context from auto to previous context
|
||||||
if dclcontext != PAUTO {
|
|
||||||
Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
|
|
||||||
}
|
|
||||||
types.Popdcl()
|
types.Popdcl()
|
||||||
funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
|
var e funcStackEnt
|
||||||
if Curfn == nil {
|
funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
|
||||||
dclcontext = PEXTERN
|
Curfn, dclcontext = e.curfn, e.dclcontext
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// structs, functions, and methods.
|
// structs, functions, and methods.
|
||||||
|
@ -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 {
|
if len(compilequeue) != 0 {
|
||||||
Fatalf("%d uncompiled functions", len(compilequeue))
|
Fatalf("%d uncompiled functions", len(compilequeue))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user