Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e9cd2dc

Browse files
committed
C++: Implement 'lambdaCreation' and 'lambdaCall' for models-as-data.
1 parent 4d5f158 commit e9cd2dc

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,10 +1290,16 @@ predicate nodeIsHidden(Node n) {
12901290
class LambdaCallKind = Unit;
12911291

12921292
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
1293-
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { none() }
1293+
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
1294+
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
1295+
exists(kind)
1296+
}
12941297

12951298
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
1296-
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
1299+
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
1300+
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
1301+
exists(kind)
1302+
}
12971303

12981304
/** Extra data-flow steps needed for lambda flow analysis. */
12991305
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }

cpp/ql/test/library-tests/dataflow/models-as-data/tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,17 +437,17 @@ void madCallArg0WithValue(void (*fun_ptr)(int), int value); // $ interpretElemen
437437
int madCallReturnValueIgnoreFunction(void (*fun_ptr)(int), int value); // $ interpretElement
438438

439439
int getTainted() { return source(); }
440-
void useValue(int x) { sink(x); }
440+
void useValue(int x) { sink(x); } // $ ir
441441
void dontUseValue(int x) { }
442442

443443
void test_function_pointers() {
444444
sink(madCallArg0ReturnToReturn(&notASource));
445-
sink(madCallArg0ReturnToReturn(&getTainted)); // $ MISSING: ir
445+
sink(madCallArg0ReturnToReturn(&getTainted)); // $ ir
446446
sink(madCallArg0ReturnToReturn(&source)); // $ MISSING: ir
447447
sink(madCallArg0ReturnToReturnFirst(&source).first); // $ MISSING: ir
448448
sink(madCallArg0ReturnToReturnFirst(&source).second);
449449
madCallArg0WithValue(&useValue, 0);
450-
madCallArg0WithValue(&useValue, source()); // $ MISSING: ir
450+
madCallArg0WithValue(&useValue, source());
451451
madCallArg0WithValue(&sink, source()); // $ MISSING: ir
452452
madCallReturnValueIgnoreFunction(&sink, source());
453453
sink(madCallReturnValueIgnoreFunction(&dontUseValue, source())); // $ ir

0 commit comments

Comments
 (0)