cmd/6l, cmd/8l: emit no-ops to separate zero-stack funcs from nosplits.
The stack overflow checker in the linker uses the spadj field
to determine whether stack space will be large enough or not.
When spadj=0, the checker treats the function as a nosplit
and emits an error although the program is correct.
Also enable the stack checker in 8l.
Fixes #4316.
R=rsc, golang-dev
CC=golang-dev
https://golang.org/cl/6855088
diff --git a/test/fixedbugs/issue4316.go b/test/fixedbugs/issue4316.go
new file mode 100644
index 0000000..bb18a08
--- /dev/null
+++ b/test/fixedbugs/issue4316.go
@@ -0,0 +1,64 @@
+// run
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 4316: the stack overflow check in the linker
+// is confused when it encounters a split-stack function
+// that needs 0 bytes of stack space.
+
+package main
+
+type Peano *Peano
+
+func makePeano(n int) *Peano {
+ if n == 0 {
+ return nil
+ }
+ p := Peano(makePeano(n - 1))
+ return &p
+}
+
+var countArg Peano
+var countResult int
+
+func countPeano() {
+ if countArg == nil {
+ countResult = 0
+ return
+ }
+ countArg = *countArg
+ countPeano()
+ countResult++
+}
+
+var s = "(())"
+var pT = 0
+
+func p() {
+ if pT >= len(s) {
+ return
+ }
+ if s[pT] == '(' {
+ pT += 1
+ p()
+ if pT < len(s) && s[pT] == ')' {
+ pT += 1
+ } else {
+ return
+ }
+ p()
+ }
+}
+
+func main() {
+ countArg = makePeano(4096)
+ countPeano()
+ if countResult != 4096 {
+ println("countResult =", countResult)
+ panic("countResult != 4096")
+ }
+
+ p()
+}