mirror of
https://github.com/github/codeql.git
synced 2025-12-22 03:36:30 +01:00
C++: Solve non-monotonic issue by unfolding dataflow-related predicates until we get to the SSA implementations of them.
This commit is contained in:
committed by
Geoffrey White
parent
cfc1a3db22
commit
2bea0adb92
@@ -436,22 +436,21 @@ class IndirectionPosition extends Position, TIndirectionPosition {
|
|||||||
newtype TPosition =
|
newtype TPosition =
|
||||||
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
|
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
|
||||||
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
|
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
|
||||||
hasOperandAndIndex(_, any(CallInstruction call).getArgumentOperand(argumentIndex),
|
Ssa::hasIndirectOperand(any(CallInstruction call).getArgumentOperand(argumentIndex),
|
||||||
indirectionIndex)
|
indirectionIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
private newtype TReturnKind =
|
private newtype TReturnKind =
|
||||||
TNormalReturnKind(int indirectionIndex) {
|
TNormalReturnKind(int indirectionIndex) {
|
||||||
exists(IndirectReturnNode return |
|
Ssa::hasIndirectOperand(any(ReturnValueInstruction ret).getReturnAddressOperand(),
|
||||||
return.isNormalReturn() and
|
indirectionIndex + 1) // We subtract one because the return loads the value.
|
||||||
indirectionIndex = return.getIndirectionIndex() - 1 // We subtract one because the return loads the value.
|
or
|
||||||
)
|
indirectionIndex = 0 // TODO: very much a bodge so that it works on the test that has no return statements
|
||||||
or indirectionIndex = 0 // TODO: very much a bodge so that it works on the test that has no return statements
|
|
||||||
} or
|
} or
|
||||||
TIndirectReturnKind(int argumentIndex, int indirectionIndex) {
|
TIndirectReturnKind(int argumentIndex, int indirectionIndex) {
|
||||||
exists(IndirectReturnNode return |
|
exists(Ssa::FinalParameterUse use |
|
||||||
return.isParameterReturn(argumentIndex) and
|
hasFinalParameterNode(use, _, indirectionIndex) and
|
||||||
indirectionIndex = return.getIndirectionIndex()
|
use.getArgumentIndex() = argumentIndex
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,14 +53,22 @@ private newtype TIRDataFlowNode =
|
|||||||
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||||
} or
|
} or
|
||||||
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
||||||
exists(Ssa::FinalParameterUse use |
|
hasFinalParameterNode(_, p, indirectionIndex)
|
||||||
use.getParameter() = p and
|
|
||||||
use.getIndirectionIndex() = indirectionIndex and
|
|
||||||
parameterIsRedefined(p)
|
|
||||||
)
|
|
||||||
} or
|
} or
|
||||||
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
||||||
TInitialGlobalValue(Ssa::GlobalDef globalUse)
|
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
|
||||||
|
FlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `(p, indirectionIndex)` should define a `TFinalParameterNode`
|
||||||
|
* entry because `use` represents the final use of a parameter that has been
|
||||||
|
* written to in the enclosing function of `p`.
|
||||||
|
*/
|
||||||
|
predicate hasFinalParameterNode(Ssa::FinalParameterUse use, Parameter p, int indirectionIndex) {
|
||||||
|
use.getParameter() = p and
|
||||||
|
use.getIndirectionIndex() = indirectionIndex and
|
||||||
|
parameterIsRedefined(p)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
|
* Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
|
||||||
|
|||||||
@@ -70,18 +70,22 @@ private module SourceVariables {
|
|||||||
|
|
||||||
import SourceVariables
|
import SourceVariables
|
||||||
|
|
||||||
|
predicate hasIndirectOperand(Operand op, int indirectionIndex) {
|
||||||
|
exists(CppType type, int m |
|
||||||
|
not ignoreOperand(op) and
|
||||||
|
type = getLanguageType(op) and
|
||||||
|
m = countIndirectionsForCppType(type) and
|
||||||
|
indirectionIndex = [1 .. m]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the `(operand, indirectionIndex)` columns should be
|
* Holds if the `(operand, indirectionIndex)` columns should be
|
||||||
* assigned a `RawIndirectOperand` value.
|
* assigned a `RawIndirectOperand` value.
|
||||||
*/
|
*/
|
||||||
predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
|
predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
|
||||||
exists(CppType type, int m |
|
hasIndirectOperand(op, indirectionIndex) and
|
||||||
not ignoreOperand(op) and
|
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
|
||||||
type = getLanguageType(op) and
|
|
||||||
m = countIndirectionsForCppType(type) and
|
|
||||||
indirectionIndex = [1 .. m] and
|
|
||||||
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -403,6 +407,8 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
|||||||
|
|
||||||
Parameter getParameter() { result = p }
|
Parameter getParameter() { result = p }
|
||||||
|
|
||||||
|
int getArgumentIndex() { result = p.getIndex() }
|
||||||
|
|
||||||
override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) }
|
override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) }
|
||||||
|
|
||||||
override int getIndirection() { result = ind + 1 }
|
override int getIndirection() { result = ind + 1 }
|
||||||
|
|||||||
Reference in New Issue
Block a user