gordonklaus / ineffassign

Detect ineffectual assignments in Go code.
MIT License
390 stars 22 forks source link

defer + named-return-value false negative #89

Open chrchang opened 1 month ago

chrchang commented 1 month ago
package main

import (
        "errors"
        "fmt"
)

func decorateErr(errPtr *error) {
        *errPtr = fmt.Errorf("blah blah blah %v", *errPtr)
}

func sampleFunc() (err error) {
        defer decorateErr(&err)
        err = errors.New("this is an ineffective assignment")
        return nil
}

func main() {
        err := sampleFunc()
        fmt.Printf("%v", err)
}

The ineffective assignment is recognized if I remove "defer decorateErr(&err)".

gordonklaus commented 1 month ago

Thanks for the report.

The reason this ineffective assignment is not recognized is actually not due to the defer but to the &err. Whenever the tool sees &x, it says "x escapes" and gives up on tracking it, because it's a more complicated problem to track where pointers flow through a program. As far as the tool is concerned, decorateErr(&err) (as seen from the outside) might possibly use *err instead of just assigning to it.

Until the tool is completely rewritten to use a full pointer analysis (if ever), it's beyond its scope to recognize this case.