MCPcopy
hub / github.com/uber-go/nilaway / learnNilness

Function learnNilness

assertion/function/functioncontracts/infer.go:160–200  ·  view source on GitHub ↗

learnNilness learns nilness for the block succ, extended from one nilnessTable table of its predecessor pred. The function creates a new nilnessTable that stores **only newly learned** nilness for succ block and a bool flag that indicates whether a conflict is seen when going to succ block from pred

(succ *ssa.BasicBlock, pred *ssa.BasicBlock, table nilnessTable)

Source from the content-addressed store, hash-verified

158// not learn nilness for al kinds of conditions. For now we support only what is supported in
159// the function branch.
160func learnNilness(succ *ssa.BasicBlock, pred *ssa.BasicBlock, table nilnessTable) (nilnessTable, bool) {
161 lTable := nilnessTable{} // learned nilnessTable
162 eqSucc, neSucc, binOp := branch(pred)
163 // TODO: for now we learn nilness from only these two condition: ? == ? and ? != ?
164 if binOp == nil || eqSucc == nil || neSucc == nil {
165 // TODO: only binOp == nil is sufficient, but nilaway would not be happy with it.
166 return lTable, true
167 }
168 // TODO: each successor should learn a different nilness in terms of the variable
169 // involved in the condition.
170 xnil := table.nilnessOf(binOp.X)
171 ynil := table.nilnessOf(binOp.Y)
172
173 // Both operands are known of nilness.
174 // Determine whether the branch is reachable.
175 if xnil != unknown && ynil != unknown {
176 if (xnil == ynil && succ == eqSucc) || (xnil != ynil && succ == neSucc) {
177 return lTable, true
178 }
179 // conflict
180 return lTable, false
181 }
182
183 // Only one operand is known of nilness.
184 if ynil == unknown {
185 // learn the nilness of Y
186 if succ == eqSucc {
187 lTable.expandNilness(binOp.Y, xnil)
188 } else {
189 lTable.expandNilness(binOp.Y, xnil.negate())
190 }
191 } else {
192 // learn the nilness of X
193 if succ == eqSucc {
194 lTable.expandNilness(binOp.X, ynil)
195 } else {
196 lTable.expandNilness(binOp.X, ynil.negate())
197 }
198 }
199 return lTable, true
200}
201
202// deriveContracts checks nilness of parameter and return values at every exit block to infer
203// contracts.

Callers 1

inferContractsFunction · 0.85

Calls 4

expandNilnessMethod · 0.95
branchFunction · 0.85
nilnessOfMethod · 0.80
negateMethod · 0.80

Tested by

no test coverage detected