Skip to content

Commit 9b8154c

Browse files
authored
ruleguard: continue pattern matching for multi-match patterns (#340)
This is probably a temporary and sub-optimal solution, but it should do for now. Since matches are much more rare than pattern misses, we do the check under the `matched` condition. Extra condition shouldn't make anything measurably slower there. Fixes #339
1 parent 00cd1e9 commit 9b8154c

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

analyzer/testdata/src/regression/issue115.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ func testIssue115() {
44
intFunc := func() int { return 19 }
55
stringFunc := func() string { return "19" }
66

7-
println(13)
8-
println(43 + 5)
7+
println(13, "!constexpr int")
8+
println(43+5, "!constexpr int")
99

10-
println("foo") // want `\Q"foo" is not a constexpr int`
11-
println(intFunc()) // want `\QintFunc() is not a constexpr int`
12-
println(stringFunc()) // want `\QstringFunc() is not a constexpr int`
10+
println("foo", "!constexpr int") // want `\Q"foo" is not a constexpr int`
11+
println(intFunc(), "!constexpr int") // want `\QintFunc() is not a constexpr int`
12+
println(stringFunc(), "!constexpr int") // want `\QstringFunc() is not a constexpr int`
1313
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package regression
2+
3+
func _() {
4+
println("339") // want `\Qpattern1`
5+
println("x") // want `\Qpattern2`
6+
7+
println("339") // want `\Qpattern1`
8+
9+
println("x")
10+
}
11+
12+
func _() {
13+
println("x") // want `\Qpattern2`
14+
println("339") // want `\Qpattern1`
15+
16+
println("x") // want `\Qpattern2`
17+
println("339") // want `\Qpattern1`
18+
19+
println("x")
20+
println("x") // want `\Qpattern2`
21+
println("339")
22+
}

analyzer/testdata/src/regression/rules.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build ignore
12
// +build ignore
23

34
package gorules
@@ -21,7 +22,7 @@ func issue72(m dsl.Matcher) {
2122
}
2223

2324
func issue115(m dsl.Matcher) {
24-
m.Match(`println($x)`).
25+
m.Match(`println($x, "!constexpr int")`).
2526
Where(!(m["x"].Const && m["x"].Type.Is("int"))).
2627
Report("$x is not a constexpr int")
2728
}
@@ -45,3 +46,8 @@ func issue291(m dsl.Matcher) {
4546
At(m["iota"]).
4647
Report("good, have explicit type")
4748
}
49+
50+
func issue339(m dsl.Matcher) {
51+
m.Match(`println("339"); println("x")`).Report("pattern1")
52+
m.Match(`println("x"); println("339")`).Report("pattern2")
53+
}

ruleguard/runner.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func (rr *rulesRunner) runRules(n ast.Node) {
233233
profiling.Leave(rr.bgContext)
234234
}
235235

236-
if matched {
236+
if matched && !multiMatchTags[tag] {
237237
break
238238
}
239239
}
@@ -414,3 +414,10 @@ func truncateText(s string, maxLen int) string {
414414
right := s[len(s)-rightLen:]
415415
return left + placeholder + right
416416
}
417+
418+
var multiMatchTags = [nodetag.NumBuckets]bool{
419+
nodetag.BlockStmt: true,
420+
nodetag.CaseClause: true,
421+
nodetag.CommClause: true,
422+
nodetag.File: true,
423+
}

0 commit comments

Comments
 (0)