C++: Solve non-monotonic issue by unfolding dataflow-related predicates until we get to the SSA implementations of them.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-01-30 13:11:10 +00:00
committed by Geoffrey White
parent cfc1a3db22
commit 2bea0adb92
3 changed files with 35 additions and 22 deletions

View File

@@ -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
) )
} }

View File

@@ -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

View File

@@ -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 }