Skip to content

Commit 0a83c9b

Browse files
committed
go/ir: consider fake exits when building (post-)dominator frontier
We correctly considered fake exits when building the (post-)dominator tree, but forgot to do so when calculating the frontier. This would lead to missing phi and sigma nodes, ultimately resulting in returning wrong values. Closes gh-949 (cherry picked from commit 390eb5b)
1 parent 5a1275a commit 0a83c9b

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

go/ir/builder_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ func h(error)
482482
}
483483
}
484484
}
485-
if expected := 1; phis != expected {
485+
if expected := 3; phis != expected {
486486
g.WriteTo(os.Stderr)
487487
t.Errorf("expected %d Phi nodes (for the range index), got %d", expected, phis)
488488
}

go/ir/dom.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ func printDomTreeDot(buf io.Writer, f *Function) {
423423
for _, pred := range b.Preds {
424424
fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.dom.pre, v.pre)
425425
}
426+
427+
if f.fakeExits.Has(b) {
428+
fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0,color=red];\n", b.dom.pre, f.Exit.dom.pre)
429+
}
426430
}
427431
fmt.Fprintln(buf, "}")
428432
}
@@ -456,6 +460,10 @@ func printPostDomTreeDot(buf io.Writer, f *Function) {
456460
for _, pred := range b.Preds {
457461
fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.pdom.pre, v.pre)
458462
}
463+
464+
if f.fakeExits.Has(b) {
465+
fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0,color=red];\n", b.dom.pre, f.Exit.dom.pre)
466+
}
459467
}
460468
fmt.Fprintln(buf, "}")
461469
}

go/ir/lift.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,16 @@ func (df domFrontier) add(u, v *BasicBlock) {
7979
// the DF -> IDF step.
8080
func (df domFrontier) build(fn *Function) {
8181
for _, b := range fn.Blocks {
82-
if len(b.Preds) >= 2 {
83-
for _, p := range b.Preds {
82+
preds := b.Preds[0:len(b.Preds):len(b.Preds)]
83+
if b == fn.Exit {
84+
for i, v := range fn.fakeExits.values {
85+
if v {
86+
preds = append(preds, fn.Blocks[i])
87+
}
88+
}
89+
}
90+
if len(preds) >= 2 {
91+
for _, p := range preds {
8492
runner := p
8593
for runner != b.dom.idom {
8694
df.add(runner, b)
@@ -105,8 +113,12 @@ func (rdf postDomFrontier) add(u, v *BasicBlock) {
105113

106114
func (rdf postDomFrontier) build(fn *Function) {
107115
for _, b := range fn.Blocks {
108-
if len(b.Succs) >= 2 {
109-
for _, s := range b.Succs {
116+
succs := b.Succs[0:len(b.Succs):len(b.Succs)]
117+
if fn.fakeExits.Has(b) {
118+
succs = append(succs, fn.Exit)
119+
}
120+
if len(succs) >= 2 {
121+
for _, s := range succs {
110122
runner := s
111123
for runner != b.pdom.idom {
112124
rdf.add(runner, b)

staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package pkg
22

33
import (
44
"context"
5+
"fmt"
56
"net/http"
67
"strings"
78
)
@@ -36,3 +37,12 @@ func fn3() {
3637
stubPointer()
3738
stubInt()
3839
}
40+
41+
func fn4() error {
42+
// Test for https://github.com/dominikh/go-tools/issues/949
43+
if true {
44+
return fmt.Errorf("")
45+
}
46+
for {
47+
}
48+
}

0 commit comments

Comments
 (0)