Skip to content

Commit 85cfa4d

Browse files
committed
cmd/compile: handle degenerate write barrier case
If both branches of a write barrier test go to the same block, then there's no unsafe points. This can only happen if the resulting memory state is somehow dead, which can only occur in degenerate cases, like infinite loops. No point in cleaning up the useless branch in these situations. Fixes #26024. Change-Id: I93a7df9fdf2fc94c6c4b1fe61180dc4fd4a0871f Reviewed-on: https://go-review.googlesource.com/123655 Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
1 parent 0029cd4 commit 85cfa4d

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/cmd/compile/internal/gc/plive.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,11 @@ func (lv *Liveness) markUnsafePoints() {
692692
lv.f.Fatalf("expected branch at write barrier block %v", wbBlock)
693693
}
694694
s0, s1 := wbBlock.Succs[0].Block(), wbBlock.Succs[1].Block()
695+
if s0 == s1 {
696+
// There's no difference between write barrier on and off.
697+
// Thus there's no unsafe locations. See issue 26024.
698+
continue
699+
}
695700
if s0.Kind != ssa.BlockPlain || s1.Kind != ssa.BlockPlain {
696701
lv.f.Fatalf("expected successors of write barrier block %v to be plain", wbBlock)
697702
}

test/fixedbugs/issue26024.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// compile
2+
// Copyright 2018 The Go Authors. All rights reserved.
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
6+
package r
7+
8+
// f compiles into code where no stores remain in the two successors
9+
// of a write barrier block; i.e., they are empty. Pre-fix, this
10+
// results in an unexpected input to markUnsafePoints, that expects to
11+
// see a pair of non-empty plain blocks.
12+
func f() {
13+
var i int
14+
var s string
15+
for len(s) < len(s) {
16+
i++
17+
s = "a"
18+
}
19+
var b bool
20+
var sa []string
21+
for true {
22+
sa = []string{""}
23+
for b || i == 0 {
24+
}
25+
b = !b
26+
_ = sa
27+
}
28+
}

0 commit comments

Comments
 (0)