go icon indicating copy to clipboard operation
go copied to clipboard

cmd/vet: diagnose set and not used

Open rsc opened this issue 12 years ago • 9 comments

If you have:

x := 1
_ = x
x = 2

the spec allows this program and therefore the compilers accept it without comment.

However, it would be nice if vet could tell you about 'set and not used' on the final
line.
Maybe this falls out of some code Alan already has lying around. Maybe not.

rsc avatar Aug 07 '13 16:08 rsc

Comment 1:

Deferring to 1.3.

Labels changed: added go1.3maybe, removed go1.2maybe.

robpike avatar Aug 20 '13 06:08 robpike

Comment 2:

Labels changed: removed go1.3maybe.

robpike avatar Aug 20 '13 23:08 robpike

Comment 3:

Labels changed: added go1.3maybe.

rsc avatar Nov 27 '13 18:11 rsc

Comment 4:

Labels changed: added release-none, removed go1.3maybe.

rsc avatar Dec 04 '13 01:12 rsc

Comment 5:

Labels changed: added repo-tools.

rsc avatar Dec 04 '13 01:12 rsc

Comment 6:

(Sorry, didn't notice this till today.)
To detect this situation in general, we need to find all assignments
to non-address-taken local variables (except named return parameters)
on which there is no control flow path leading to a reference to that
var.
Obviously that means we'd need to build a syntax-level control-flow graph.
Updates of named return parameters are exempt because their effect may
be observed via return or a defer/panic/recover.
Address-taken vars are exempted because we cannot tell with only local
analysis whether the update might be observed through a pointer.  
The following expressions e are considered address-taken:
Base cases:
- &e, obviously.
- var e T; _ = func() { ...e... }
  Free variables of a function literal are considered address-taken
  since the closure holds the address, and we cannot know in general
  when the func is called.
- e.Method, where e has type T and the method receiver is *T.
Induction rules:
- from (e) to e
- from e[:] to e  (iff e has array type)
- from e[i] to e  (iff e has array type)
- from e.f to e
This information is easily obtained during SSA construction.
(Although the SSA builder would optimize the dead stores away, this
can be suppressed by skipping the conversion to full SSA, i.e. ssadump
-build=N.)  But vet probably doesn't want to depend on go/ssa...
The lower-hanging fruit might be assignments to non-AT local vars
whose declaration is in the same or an outer lexical block, with no
intervening for-loop blocks (and ignore loops created with goto), with
no references in subsequent statements.  This doesn't need a CFG, and
I can probably factor out a useful little AT pass that would make this
trivial.

Owner changed to @adonovan.

adonovan avatar Nov 10 '14 22:11 adonovan

The https://github.com/gordonklaus/ineffassign tool performs a similar check and I have found it has a very low false-positive rate.

dgryski avatar Oct 20 '17 18:10 dgryski

@dgryski I believe staticcheck also has some relevant checks, see SA4xxx category at https://staticcheck.io/docs/staticcheck#checks. /cc @dominikh

dmitshur avatar Oct 22 '17 04:10 dmitshur

@dgryski I believe staticcheck also has some relevant checks, see SA4xxx category at https://staticcheck.io/docs/staticcheck#checks. /cc @dominikh

Now the doc locates at https://staticcheck.dev/docs/checks/.

linsite avatar Dec 05 '25 02:12 linsite