Skip to content

Commit 1da42cb

Browse files
authored
Merge pull request #20023 from MathiasVP/dataflow-for-functors
C++: Better dataflow for function objects
2 parents 649c883 + 053a749 commit 1da42cb

File tree

13 files changed

+262
-23
lines changed

13 files changed

+262
-23
lines changed

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

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,16 +1382,89 @@ predicate neverSkipInPathGraph(Node n) {
13821382
exists(n.asIndirectDefinition())
13831383
}
13841384

1385-
class LambdaCallKind = Unit;
1385+
private newtype TLambdaCallKind =
1386+
TFunctionPointer() or
1387+
TFunctor()
1388+
1389+
class LambdaCallKind extends TLambdaCallKind {
1390+
predicate isFunctionPointer() { this = TFunctionPointer() }
1391+
1392+
predicate isFunctor() { this = TFunctor() }
1393+
1394+
string toString() {
1395+
this.isFunctionPointer() and
1396+
result = "Function pointer kind"
1397+
or
1398+
this.isFunctor() and
1399+
result = "Functor kind"
1400+
}
1401+
}
1402+
1403+
private class ConstructorCallInstruction extends CallInstruction {
1404+
Cpp::Class constructedType;
1405+
1406+
ConstructorCallInstruction() {
1407+
this.getStaticCallTarget().(Cpp::Constructor).getDeclaringType() = constructedType
1408+
}
1409+
1410+
Cpp::Class getConstructedType() { result = constructedType }
1411+
}
1412+
1413+
private class OperatorCall extends Cpp::MemberFunction {
1414+
OperatorCall() { this.hasName("operator()") }
1415+
}
1416+
1417+
private predicate isFunctorCreationWithoutConstructor(Node creation, OperatorCall operator) {
1418+
exists(UninitializedInstruction init, Instruction dest |
1419+
// A construction of an object with no constructor. In this case we use
1420+
// the `UninitializedInstruction` as the creation node.
1421+
init = creation.asInstruction() and
1422+
dest = init.getDestinationAddress() and
1423+
not any(ConstructorCallInstruction constructorCall).getThisArgument() = dest and
1424+
operator.getDeclaringType() = init.getResultType()
1425+
)
1426+
or
1427+
// Workaround for an extractor bug. In this snippet:
1428+
// ```
1429+
// struct S { };
1430+
// void f(S);
1431+
// f(S());
1432+
// ```
1433+
// The expression `S()` is represented as a 0 literal in the database.
1434+
exists(ConstantValueInstruction constant |
1435+
constant.getValue() = "0" and
1436+
creation.asInstruction() = constant and
1437+
constant.getResultType() = operator.getDeclaringType()
1438+
)
1439+
}
1440+
1441+
private predicate isFunctorCreationWithConstructor(Node creation, OperatorCall operator) {
1442+
exists(DataFlowCall constructorCall, IndirectionPosition pos |
1443+
// A construction of an object with a constructor. In this case we use
1444+
// the post-update node of the qualifier
1445+
pos.getArgumentIndex() = -1 and
1446+
isArgumentNode(creation.(PostUpdateNode).getPreUpdateNode(), constructorCall, pos) and
1447+
operator.getDeclaringType() =
1448+
constructorCall.asCallInstruction().(ConstructorCallInstruction).getConstructedType()
1449+
)
1450+
}
13861451

13871452
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
13881453
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
1389-
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
1390-
exists(kind)
1454+
kind.isFunctionPointer() and
1455+
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable()
1456+
or
1457+
kind.isFunctor() and
1458+
exists(OperatorCall operator | operator = c.asSourceCallable() |
1459+
isFunctorCreationWithoutConstructor(creation, operator)
1460+
or
1461+
isFunctorCreationWithConstructor(creation, operator)
1462+
)
13911463
}
13921464

13931465
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
13941466
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
1467+
kind.isFunctionPointer() and
13951468
(
13961469
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
13971470
or
@@ -1400,8 +1473,15 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
14001473
// has a result for `getStaticCallTarget`.
14011474
not exists(call.getStaticCallTarget()) and
14021475
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
1403-
) and
1404-
exists(kind)
1476+
)
1477+
or
1478+
kind.isFunctor() and
1479+
(
1480+
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
1481+
or
1482+
not exists(call.getStaticCallTarget()) and
1483+
call.asCallInstruction().getThisArgumentOperand() = receiver.asOperand()
1484+
)
14051485
}
14061486

14071487
/** Extra data-flow steps needed for lambda flow analysis. */

cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
725725
* Gets the variable that is uninitialized.
726726
*/
727727
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
728+
729+
/**
730+
* Gets the operand that provides the address of the ___location to which the
731+
* uninitialized value will be stored.
732+
*/
733+
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
734+
735+
/**
736+
* Gets the instruction whose result provides the address of the ___location to
737+
* which the value will be stored, if an exact definition is available.
738+
*/
739+
final Instruction getDestinationAddress() {
740+
result = this.getDestinationAddressOperand().getDef()
741+
}
728742
}
729743

730744
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
725725
* Gets the variable that is uninitialized.
726726
*/
727727
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
728+
729+
/**
730+
* Gets the operand that provides the address of the ___location to which the
731+
* uninitialized value will be stored.
732+
*/
733+
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
734+
735+
/**
736+
* Gets the instruction whose result provides the address of the ___location to
737+
* which the value will be stored, if an exact definition is available.
738+
*/
739+
final Instruction getDestinationAddress() {
740+
result = this.getDestinationAddressOperand().getDef()
741+
}
728742
}
729743

730744
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
725725
* Gets the variable that is uninitialized.
726726
*/
727727
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
728+
729+
/**
730+
* Gets the operand that provides the address of the ___location to which the
731+
* uninitialized value will be stored.
732+
*/
733+
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
734+
735+
/**
736+
* Gets the instruction whose result provides the address of the ___location to
737+
* which the value will be stored, if an exact definition is available.
738+
*/
739+
final Instruction getDestinationAddress() {
740+
result = this.getDestinationAddressOperand().getDef()
741+
}
728742
}
729743

730744
/**
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved support for dataflow through function objects and lambda expressions.

cpp/ql/test/library-tests/dataflow/external-models/flow.expected

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ models
2121
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
2222
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
2323
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
24-
| 23 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
25-
| 24 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
26-
| 25 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
27-
| 26 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
28-
| 27 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
24+
| 23 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
25+
| 24 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
26+
| 25 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
27+
| 26 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
28+
| 27 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
29+
| 28 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
2930
edges
30-
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:27 |
31+
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:28 |
3132
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
3233
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
3334
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
@@ -36,10 +37,10 @@ edges
3637
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
3738
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
3839
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
39-
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:27 |
40-
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:25 |
41-
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:24 |
42-
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:26 |
40+
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:28 |
41+
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:26 |
42+
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:25 |
43+
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:27 |
4344
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
4445
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
4546
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
@@ -51,28 +52,49 @@ edges
5152
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
5253
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
5354
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
54-
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:25 |
55+
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:26 |
5556
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
5657
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
5758
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
58-
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:24 |
59+
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:25 |
5960
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
6061
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
6162
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
62-
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:26 |
63+
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:27 |
6364
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
6465
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
6566
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
6667
| test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
6768
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
6869
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
6970
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
70-
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:23 |
71+
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:24 |
7172
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
7273
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
7374
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
7475
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
7576
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
77+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
78+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
79+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
80+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
81+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
82+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
83+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
84+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:88:22:88:22 | y | provenance | |
85+
| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:1 |
86+
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
87+
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
88+
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
89+
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
90+
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
91+
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
92+
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
93+
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:104:62:104:62 | x | provenance | |
94+
| test.cpp:97:26:97:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
95+
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
96+
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
97+
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
7698
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
7799
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
78100
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
@@ -209,6 +231,28 @@ nodes
209231
| test.cpp:56:2:56:18 | ... = ... | semmle.label | ... = ... |
210232
| test.cpp:56:8:56:16 | call to ymlSource | semmle.label | call to ymlSource |
211233
| test.cpp:59:55:59:64 | *& ... [x] | semmle.label | *& ... [x] |
234+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
235+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
236+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
237+
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
238+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
239+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
240+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
241+
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
242+
| test.cpp:68:22:68:22 | y | semmle.label | y |
243+
| test.cpp:69:11:69:11 | y | semmle.label | y |
244+
| test.cpp:74:22:74:22 | y | semmle.label | y |
245+
| test.cpp:75:11:75:11 | y | semmle.label | y |
246+
| test.cpp:82:22:82:22 | y | semmle.label | y |
247+
| test.cpp:83:11:83:11 | y | semmle.label | y |
248+
| test.cpp:88:22:88:22 | y | semmle.label | y |
249+
| test.cpp:89:11:89:11 | y | semmle.label | y |
250+
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
251+
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
252+
| test.cpp:97:26:97:26 | x | semmle.label | x |
253+
| test.cpp:101:26:101:26 | x | semmle.label | x |
254+
| test.cpp:103:63:103:63 | x | semmle.label | x |
255+
| test.cpp:104:62:104:62 | x | semmle.label | x |
212256
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
213257
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
214258
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |

cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ extensions:
1616
- ["", "", False, "ymlStepManual", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
1717
- ["", "", False, "ymlStepGenerated", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
1818
- ["", "", False, "ymlStepManual_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
19-
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
19+
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
20+
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]

cpp/ql/test/library-tests/dataflow/external-models/sinks.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99
| test.cpp:33:10:33:11 | z2 | test-sink |
1010
| test.cpp:36:10:36:11 | z3 | test-sink |
1111
| test.cpp:48:16:48:16 | x | test-sink |
12+
| test.cpp:69:11:69:11 | y | test-sink |
13+
| test.cpp:75:11:75:11 | y | test-sink |
14+
| test.cpp:83:11:83:11 | y | test-sink |
15+
| test.cpp:89:11:89:11 | y | test-sink |

0 commit comments

Comments
 (0)