uber-go / nilaway

Static analysis tool to detect potential nil panics in Go code
Apache License 2.0
3.06k stars 60 forks source link

False positive when a deep read uses an expression #256

Open cgetzen opened 3 months ago

cgetzen commented 3 months ago
func false_positive() {
    outer := make(map[string]map[string]int)
    inner := []string{"a"}

    if _, ok := outer[inner[0]]; !ok {
        outer[inner[0]] = map[string]int{}
    }

    outer[inner[0]]["value"] = 1
}
// error: Potential nil panic detected. Observed nil flow from source to dereference point:
//        - deep read from local variable `outer` lacking guarding; written to at an index

// When the expression is assigned to a variable, it succeeds
func true_negative() {
    outer := make(map[string]map[string]int)
    inner := []string{"a"}
    x := inner[0]

    if _, ok := outer[x]; !ok {
        outer[x] = map[string]int{}
    }

    outer[x]["value"] = 1
}
cgetzen commented 3 months ago

I'm hesitant to create another issue, as I think the root cause may be similar:

func false_positive() error {
    var slice []int
    sliceLen := len(slice)

    for idx := 0; idx < sliceLen; idx += 1 {
        _ = slice[0:idx]
    }
    return nil
}
// error: Potential nil panic detected. Observed nil flow from source to dereference point:
//        -  unassigned variable `slice` sliced into

func true_negative() error {
    var slice []int

    for idx := 0; idx < len(slice); idx += 1 {
        _ = slice[0:idx]
    }
    return nil
}