Field Assignment Never Observed
ID |
go.field_assignment_never_observed |
Severity |
high |
Remediation Complexity |
simple |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
CWE:563, correctness, reliability |
Description
Reports an assignment to a field of a method’s value receiver (func (v T) m() { v.field = X })
whose write can never be observed. A value receiver is a copy made only for the duration of the
call, so a field stored into it is thrown away when the method returns.
Rationale
Methods declared on a value receiver operate on a copy of the receiver, not on the caller’s value.
Storing into a field of that copy has no effect the caller can see, and when nothing in the method
reads the receiver again the store is provably dead — almost always a sign the method was meant to
take a pointer receiver (func (v *T) m()).
To stay free of false positives the rule fires only when the receiver is a named value receiver, the
target is a direct field of that receiver (v.field), and the receiver is never used anywhere after
the assignment in the method body. Any later read leaves the write alone.
func (v T) set() {
v.x = 1 // FLAW — value receiver copy, the field write is discarded at return
}
func (v *T) set() {
v.x = 1 // OK — pointer receiver, visible to the caller
}
func (v T) set() {
v.x = 1 // OK — the receiver is read after the write
println(v.x)
}