A "RET f(SB)" wasn't assembled correctly in a leaf function with
non-zero frame size. Follows CL 371034, for MIPS(32/64)(be/le)
and S390X. Other architectures seem to do it right. Add a test.
Change-Id: I41349a7ae9862b924f3a3de2bcb55b782061ce21
Reviewed-on: https://go-review.googlesource.com/c/go/+/371214
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
q = c.newprog()
q.As = AJMP
q.Pos = p.Pos
- q.To.Type = obj.TYPE_MEM
- q.To.Offset = 0
- q.To.Reg = REGLINK
+ if retSym != nil { // retjmp
+ q.To.Type = obj.TYPE_BRANCH
+ q.To.Name = obj.NAME_EXTERN
+ q.To.Sym = retSym
+ } else {
+ q.To.Type = obj.TYPE_MEM
+ q.To.Reg = REGLINK
+ q.To.Offset = 0
+ }
q.Mark |= BRANCH
q.Spadj = +autosize
q = obj.Appendp(p, c.newprog)
q.As = ABR
q.From = obj.Addr{}
- q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_LR
+ if retTarget == nil {
+ q.To.Type = obj.TYPE_REG
+ q.To.Reg = REG_LR
+ } else {
+ q.To.Type = obj.TYPE_BRANCH
+ q.To.Sym = retTarget
+ }
q.Mark |= BRANCH
q.Spadj = autosize
break
TEXT ·leaf(SB), 4, $0-0
RET ·f3(SB)
JMP ·unreachable(SB)
+
+TEXT ·leaf2(SB), 4, $32-0 // nonzero frame size
+ RET ·f4(SB)
+ JMP ·unreachable(SB)
func f()
func leaf()
+func leaf2()
-var f1called, f2called, f3called bool
+var f1called, f2called, f3called, f4called bool
func main() {
f()
if !f3called {
panic("f3 not called")
}
+ leaf2()
+ if !f4called {
+ panic("f4 not called")
+ }
}
func f1() { f1called = true }
func f2() { f2called = true }
func f3() { f3called = true }
+func f4() { f4called = true }
func unreachable() {
panic("unreachable function called")