Skip to content

Commit 5595d7c

Browse files
committed
search decendants member (fix: #5)
1 parent f75fe5b commit 5595d7c

File tree

4 files changed

+103
-15
lines changed

4 files changed

+103
-15
lines changed

exportloopref.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,25 +257,13 @@ func (s *Searcher) isVar(loop ast.Node, expr ast.Expr) bool {
257257
func (s *Searcher) getIdentity(expr ast.Expr) *ast.Ident {
258258
switch typed := expr.(type) {
259259
case *ast.SelectorExpr:
260-
// Get parent identity; i.e. `a` of the `a.b`.
261-
parent, ok := typed.X.(*ast.Ident)
262-
if !ok {
263-
return nil
264-
}
265-
266-
// parent is a package name identity
267-
if parent.Obj == nil {
268-
return nil
269-
}
270-
271260
// Ignore if the parent is pointer ref (fix for #2)
272-
if _, ok := s.Types[parent].Type.(*types.Pointer); ok {
261+
if _, ok := s.Types[typed.X].Type.(*types.Pointer); ok {
273262
return nil
274263
}
275264

276-
// NOTE: If that is descendants member like `a.b.c`,
277-
// typed.X will be `*ast.SelectorExpr` `a.b`.
278-
return parent
265+
// Get parent identity; i.e. `a.b` of the `a.b.c`.
266+
return s.getIdentity(typed.X)
279267

280268
case *ast.Ident:
281269
// Get simple identity; i.e. `a` of the `a`.

exportloopref_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,13 @@ func TestIssue2(t *testing.T) {
3636
testdata := analysistest.TestData()
3737
analysistest.Run(t, testdata, exportloopref.Analyzer, "issue2")
3838
}
39+
40+
func TestDeep(t *testing.T) {
41+
testdata := analysistest.TestData()
42+
analysistest.Run(t, testdata, exportloopref.Analyzer, "deep")
43+
}
44+
45+
func TestDepPointer(t *testing.T) {
46+
testdata := analysistest.TestData()
47+
analysistest.Run(t, testdata, exportloopref.Analyzer, "deeppointer")
48+
}

testdata/src/deep/deep.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
type Container struct {
4+
Inner
5+
}
6+
7+
type Inner struct {
8+
Number int
9+
}
10+
11+
func main() {
12+
var array [4]*int
13+
var slice []*int
14+
var ref *int
15+
var str struct{ x *int }
16+
17+
var target = []Container{{Inner{10}}, {Inner{11}}, {Inner{12}}, {Inner{13}}}
18+
19+
// access to unsafe member
20+
println("loop expecting 10, 11, 12, 13")
21+
for i, p := range target {
22+
printp(&p.Inner.Number)
23+
slice = append(slice, &p.Inner.Number) // want "exporting a pointer for the loop variable p"
24+
array[i] = &p.Inner.Number // want "exporting a pointer for the loop variable p"
25+
if i%2 == 0 {
26+
ref = &p.Inner.Number // want "exporting a pointer for the loop variable p"
27+
str.x = &p.Inner.Number // want "exporting a pointer for the loop variable p"
28+
}
29+
}
30+
31+
println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
32+
for _, p := range slice {
33+
printp(p)
34+
}
35+
println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
36+
for _, p := range array {
37+
printp(p)
38+
}
39+
println(`captured value expecting "12" but "13"`)
40+
printp(ref)
41+
}
42+
43+
func printp(p *int) {
44+
println(*p)
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
type Container struct {
4+
Pointer *Inner
5+
}
6+
7+
type Inner struct {
8+
Number int
9+
}
10+
11+
func main() {
12+
var array [4]*int
13+
var slice []*int
14+
var ref *int
15+
var str struct{ x *int }
16+
17+
target := []Container{{&Inner{10}}, {&Inner{11}}, {&Inner{12}}, {&Inner{13}}}
18+
19+
// access to unsafe member
20+
println("loop expecting 10, 11, 12, 13")
21+
for i, p := range target {
22+
printp(&p.Pointer.Number)
23+
slice = append(slice, &p.Pointer.Number)
24+
array[i] = &p.Pointer.Number
25+
if i%2 == 0 {
26+
ref = &p.Pointer.Number
27+
str.x = &p.Pointer.Number
28+
}
29+
}
30+
31+
println(`slice expecting "10, 11, 12, 13"`)
32+
for _, p := range slice {
33+
printp(p)
34+
}
35+
println(`array expecting "10, 11, 12, 13"`)
36+
for _, p := range array {
37+
printp(p)
38+
}
39+
println(`captured value expecting "12"`)
40+
printp(ref)
41+
}
42+
43+
func printp(p *int) {
44+
println(*p)
45+
}

0 commit comments

Comments
 (0)