Go-tools: staticcheck: detect ineffective assignments that do not involve function calls

Created on 23 Sep 2017  路  7Comments  路  Source: dominikh/go-tools

Currently, SA4006 only detects unused values if the rhs of the assignment is a function call, but not for other expressions. That is because in the SSA form, those assignments are never represented in the first place.

Example:

func fn1(arg int) {
    x := 1
    x = 2
    x = 3
    fmt.Println(x)
}

func fn2(arg int) {
    x := gen()
    x = gen()
    x = gen()
    fmt.Println(x)
}

func gen() int { return 0 }

/*
foo.go:13:2: this value of x is never used (SA4006)
foo.go:14:2: this value of x is never used (SA4006)
*/
enhancement started

Most helpful comment

I had a buggy code with forgotten pointer, that hopefully could be flagged as ineffective assignment.

func foo(r Row /* this should have been a pointer */, postcode region.Postcode) {
    if r.Postcode != postcode {
        r.Postcode = postcode
    }
}

All 7 comments

If this information is removed from the SSA representation, how are you going to retrieve it?

Also we don't seem to be matching post increment/decrement or <binop>= even when they show up in SSA.

How does ineffassign do it?

It probably just looks at the AST differently than we do.

This one is really annoying and bites me all the time. Just recently, on a hobby project of mine, I've spent ~15 minutes pondering, why do I have a panic. The code used to be:

func NewFoo() (f Foo) {
    return foo{}
}

(Foo is an interface.) Then foo got some pointer fields, and instead of rewriting it into:

func NewFoo(b *Bar) (f Foo) {
    f = foo{bar: b}
    // Some stuff.
    return f
}

I accidentally miss-rewrote it into:

func NewFoo(b *Bar) (f Foo) {
    f = foo{bar: b}
    // Some stuff.
    return foo{} // N.B. Should be "f" here.
}

I guess ineffassign it is for now聽:-/

@ainar-g I'm working on it.

I had a buggy code with forgotten pointer, that hopefully could be flagged as ineffective assignment.

func foo(r Row /* this should have been a pointer */, postcode region.Postcode) {
    if r.Postcode != postcode {
        r.Postcode = postcode
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ainar-g picture ainar-g  路  4Comments

jadekler picture jadekler  路  3Comments

axcdnt picture axcdnt  路  3Comments

tonyghita picture tonyghita  路  4Comments

Shikkic picture Shikkic  路  4Comments