C++: Fix missing result in 'ModelUtil'. The problem was that 'n.asInstruction()' on line 81 wasn't necessarily a 'CallInstruction' (it could be a conversion).

This commit is contained in:
Mathias Vorreiter Pedersen
2023-10-23 19:34:25 +01:00
parent c0b04eac7c
commit b107c4c641
3 changed files with 36 additions and 30 deletions

View File

@@ -31,26 +31,35 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
)
}
/**
* Gets the node that represents the output of `call` with kind `output` at
* indirection index `indirectionIndex`.
*/
private Node callOutputWithIndirectionIndex(
CallInstruction call, FunctionOutput output, int indirectionIndex
) {
// The return value
simpleOutNode(result, call) and
output.isReturnValue() and
indirectionIndex = 0
or
// The side effect of a call on the value pointed to by an argument or qualifier
exists(int index |
result.(IndirectArgumentOutNode).getArgumentIndex() = index and
result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex - 1 and
result.(IndirectArgumentOutNode).getCallInstruction() = call and
output.isParameterDerefOrQualifierObject(index, indirectionIndex - 1)
)
or
result = getIndirectReturnOutNode(call, indirectionIndex) and
output.isReturnValueDeref(indirectionIndex)
}
/**
* Gets the instruction that holds the `output` for `call`.
*/
Node callOutput(CallInstruction call, FunctionOutput output) {
// The return value
simpleOutNode(result, call) and
output.isReturnValue()
or
// The side effect of a call on the value pointed to by an argument or qualifier
exists(int index, int indirectionIndex |
result.(IndirectArgumentOutNode).getArgumentIndex() = index and
result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex and
result.(IndirectArgumentOutNode).getCallInstruction() = call and
output.isParameterDerefOrQualifierObject(index, indirectionIndex)
)
or
exists(int ind |
result = getIndirectReturnOutNode(call, ind) and
output.isReturnValueDeref(ind)
)
result = callOutputWithIndirectionIndex(call, output, _)
}
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
@@ -76,19 +85,16 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
*/
bindingset[d]
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
exists(DataFlow::Node n | n = callOutput(call, output) and d > 0 |
exists(DataFlow::Node n, int indirectionIndex |
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
|
// The return value
result = getIndirectReturnOutNode(n.asInstruction(), d)
result = callOutputWithIndirectionIndex(call, output, indirectionIndex + d)
or
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and
// If there isn't an indirect out node for the call with indirection `d` then
// we conflate this with the underlying `CallInstruction`.
not exists(getIndirectReturnOutNode(call, d)) and
not exists(getIndirectReturnOutNode(call, indirectionIndex + d)) and
n = result
or
// The side effect of a call on the value pointed to by an argument or qualifier
exists(Operand operand, int indirectionIndex |
Ssa::outNodeHasAddressAndIndex(n, operand, indirectionIndex) and
Ssa::outNodeHasAddressAndIndex(result, operand, indirectionIndex + d)
)
)
}