C++: Fix spurious flow though and accept test changes.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-02-10 12:42:40 +00:00
parent faf9fd6253
commit 5bd7589109
3 changed files with 35 additions and 3 deletions

View File

@@ -52,12 +52,29 @@ private newtype TIRDataFlowNode =
TFinalParameterNode(Parameter p, int indirectionIndex) {
exists(Ssa::FinalParameterUse use |
use.getParameter() = p and
use.getIndirectionIndex() = indirectionIndex
use.getIndirectionIndex() = indirectionIndex and
parameterIsDefined(p)
)
} or
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
TInitialGlobalValue(Ssa::GlobalDef globalUse)
/**
* Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
* of the enclosing function of `p`.
*
* Only parameters satisfying this predicate will generate a `FinalParameterNode` transferring
* flow out of the function.
*/
private predicate parameterIsDefined(Parameter p) {
exists(Ssa::Def def |
def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() = p and
def.getIndirectionIndex() = 0 and
def.getIndirection() > 1 and
not def.getValue().asInstruction() instanceof InitializeParameterInstruction
)
}
/**
* An operand that is defined by a `FieldAddressInstruction`.
*/

View File

@@ -918,6 +918,8 @@ class Def extends DefOrUse {
Instruction getAddress() { result = this.getAddressOperand().getDef() }
/**
* Gets the indirection index of this definition.
*
* This predicate ensures that joins go from `defOrUse` to the result
* instead of the other way around.
*/
@@ -926,6 +928,19 @@ class Def extends DefOrUse {
pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirectionIndex()
}
/**
* Gets the indirection level that this definition is writing to.
* For instance, `x = y` is a definition of `x` at indirection level 1 and
* `*x = y` is a definition of `x` at indirection level 2.
*
* This predicate ensures that joins go from `defOrUse` to the result
* instead of the other way around.
*/
pragma[inline]
int getIndirection() {
pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirection()
}
Node0Impl getValue() { result = defOrUse.getValue() }
predicate isCertain() { defOrUse.isCertain() }

View File

@@ -579,7 +579,7 @@ namespace IndirectFlowThroughGlobals {
}
}
void write_to_param(int* x) { // $ ast-def=x ir-def=*x
void write_to_param(int* x) { // $ ast-def=x
int s = source();
x = &s;
}
@@ -587,5 +587,5 @@ void write_to_param(int* x) { // $ ast-def=x ir-def=*x
void test_write_to_param() {
int x = 0;
write_to_param(&x);
sink(x); // $ SPURIOUS: ast,ir
sink(x); // $ SPURIOUS: ast
}