Skip to content

go/analysis/passes/nilness: fixed slice not being considered as non-nil #291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion go/analysis/passes/nilness/nilness.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func (n nilness) String() string { return nilnessStrings[n+1] }
// or unknown given the dominating stack of facts.
func nilnessOf(stack []fact, v ssa.Value) nilness {
switch v := v.(type) {
// unwrap ChangeInterface values recursively, to detect if underlying
// unwrap ChangeInterface and Slice values recursively, to detect if underlying
// values have any facts recorded or are otherwise known with regard to nilness.
//
// This work must be in addition to expanding facts about
Expand All @@ -265,6 +265,10 @@ func nilnessOf(stack []fact, v ssa.Value) nilness {
if underlying := nilnessOf(stack, v.X); underlying != unknown {
return underlying
}
case *ssa.Slice:
if underlying := nilnessOf(stack, v.X); underlying != unknown {
return underlying
}
case *ssa.SliceToArrayPointer:
nn := nilnessOf(stack, v.X)
if slice2ArrayPtrLen(v) > 0 {
Expand Down
23 changes: 19 additions & 4 deletions go/analysis/passes/nilness/testdata/src/a/a.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ func f9(x interface {
b()
c()
}) {

x.b() // we don't catch this panic because we don't have any facts yet
xx := interface {
a()
Expand All @@ -155,11 +154,27 @@ func f9(x interface {
}
}

func f10() {
s0 := make([]string, 0)
if s0 == nil { // want "impossible condition: non-nil == nil"
print(0)
}

var s1 []string
if s1 == nil { // want "tautological condition: nil == nil"
print(0)
}
s2 := s1[:][:]
if s2 == nil { // want "tautological condition: nil == nil"
print(0)
}
}

func unknown() bool {
return false
}

func f10(a interface{}) {
func f11(a interface{}) {
switch a.(type) {
case nil:
return
Expand All @@ -170,7 +185,7 @@ func f10(a interface{}) {
}
}

func f11(a interface{}) {
func f12(a interface{}) {
switch a {
case nil:
return
Expand All @@ -190,7 +205,7 @@ type innerY struct {
value int
}

func f12() {
func f13() {
var d *Y
print(d.value) // want "nil dereference in field selection"
}