C++: Implement 'lambdaCreation' and 'lambdaCall' for models-as-data.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-04-09 14:05:32 +01:00
parent 4d5f158652
commit e9cd2dc9e1
2 changed files with 11 additions and 5 deletions

View File

@@ -1290,10 +1290,16 @@ predicate nodeIsHidden(Node n) {
class LambdaCallKind = Unit;
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { none() }
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
exists(kind)
}
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
exists(kind)
}
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }

View File

@@ -437,17 +437,17 @@ void madCallArg0WithValue(void (*fun_ptr)(int), int value); // $ interpretElemen
int madCallReturnValueIgnoreFunction(void (*fun_ptr)(int), int value); // $ interpretElement
int getTainted() { return source(); }
void useValue(int x) { sink(x); }
void useValue(int x) { sink(x); } // $ ir
void dontUseValue(int x) { }
void test_function_pointers() {
sink(madCallArg0ReturnToReturn(&notASource));
sink(madCallArg0ReturnToReturn(&getTainted)); // $ MISSING: ir
sink(madCallArg0ReturnToReturn(&getTainted)); // $ ir
sink(madCallArg0ReturnToReturn(&source)); // $ MISSING: ir
sink(madCallArg0ReturnToReturnFirst(&source).first); // $ MISSING: ir
sink(madCallArg0ReturnToReturnFirst(&source).second);
madCallArg0WithValue(&useValue, 0);
madCallArg0WithValue(&useValue, source()); // $ MISSING: ir
madCallArg0WithValue(&useValue, source());
madCallArg0WithValue(&sink, source()); // $ MISSING: ir
madCallReturnValueIgnoreFunction(&sink, source());
sink(madCallReturnValueIgnoreFunction(&dontUseValue, source())); // $ ir