Skip to content

Commit 1159508

Browse files
authored
Merge pull request github#14008 from MathiasVP/reuse-even-more-nodes
C++: Reuse even more `DataFlow::Node`s
2 parents ce229fe + 261ba8e commit 1159508

File tree

19 files changed

+168
-574
lines changed

19 files changed

+168
-574
lines changed

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,10 @@ private module IndirectOperands {
220220
int indirectionIndex;
221221

222222
IndirectOperandFromIRRepr() {
223-
exists(Operand repr |
224-
repr = Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) and
225-
nodeHasOperand(this, repr, indirectionIndex - 1)
223+
exists(Operand repr, int indirectionIndexRepr |
224+
Ssa::hasIRRepresentationOfIndirectOperand(operand, indirectionIndex, repr,
225+
indirectionIndexRepr) and
226+
nodeHasOperand(this, repr, indirectionIndexRepr)
226227
)
227228
}
228229

@@ -262,9 +263,10 @@ private module IndirectInstructions {
262263
int indirectionIndex;
263264

264265
IndirectInstructionFromIRRepr() {
265-
exists(Instruction repr |
266-
repr = Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) and
267-
nodeHasInstruction(this, repr, indirectionIndex - 1)
266+
exists(Instruction repr, int indirectionIndexRepr |
267+
Ssa::hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, repr,
268+
indirectionIndexRepr) and
269+
nodeHasInstruction(this, repr, indirectionIndexRepr)
268270
)
269271
}
270272

@@ -690,7 +692,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { storeStepImpl(node1,
690692
private predicate numberOfLoadsFromOperandRec(
691693
Operand operandFrom, Operand operandTo, int ind, boolean certain
692694
) {
693-
exists(Instruction load | Ssa::isDereference(load, operandFrom) |
695+
exists(Instruction load | Ssa::isDereference(load, operandFrom, _) |
694696
operandTo = operandFrom and ind = 0 and certain = true
695697
or
696698
numberOfLoadsFromOperand(load.getAUse(), operandTo, ind - 1, certain)
@@ -714,7 +716,7 @@ private predicate numberOfLoadsFromOperand(
714716
) {
715717
numberOfLoadsFromOperandRec(operandFrom, operandTo, n, certain)
716718
or
717-
not Ssa::isDereference(_, operandFrom) and
719+
not Ssa::isDereference(_, operandFrom, _) and
718720
not conversionFlow(operandFrom, _, _, _) and
719721
operandFrom = operandTo and
720722
n = 0 and

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

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
7474
type = getLanguageType(op) and
7575
m = countIndirectionsForCppType(type) and
7676
indirectionIndex = [1 .. m] and
77-
not exists(getIRRepresentationOfIndirectOperand(op, indirectionIndex))
77+
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
7878
)
7979
}
8080

@@ -88,7 +88,7 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
8888
type = getResultLanguageType(instr) and
8989
m = countIndirectionsForCppType(type) and
9090
indirectionIndex = [1 .. m] and
91-
not exists(getIRRepresentationOfIndirectInstruction(instr, indirectionIndex))
91+
not hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, _, _)
9292
)
9393
}
9494

@@ -610,7 +610,7 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
610610
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
611611
hasOperandAndIndex(nTo, op2, indirectionIndex - 1) and
612612
instr = op2.getDef() and
613-
isDereference(instr, op1)
613+
isDereference(instr, op1, _)
614614
)
615615
)
616616
}
@@ -684,8 +684,41 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) {
684684
)
685685
}
686686

687-
private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) {
688-
arg.argumentOf(call, _)
687+
private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction instr) {
688+
isArgumentOfCallableOperand(call, unique( | | getAUse(instr)))
689+
}
690+
691+
private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) {
692+
operand.(ArgumentOperand).getCall() = call
693+
or
694+
exists(FieldAddressInstruction fai |
695+
fai.getObjectAddressOperand() = operand and
696+
isArgumentOfCallableInstruction(call, fai)
697+
)
698+
or
699+
exists(Instruction deref |
700+
isArgumentOfCallableInstruction(call, deref) and
701+
isDereference(deref, operand, _)
702+
)
703+
or
704+
exists(Instruction instr |
705+
isArgumentOfCallableInstruction(call, instr) and
706+
conversionFlow(operand, instr, _, _)
707+
)
708+
}
709+
710+
private predicate isArgumentOfCallable(DataFlowCall call, Node n) {
711+
isArgumentOfCallableOperand(call, n.asOperand())
712+
or
713+
exists(Operand op |
714+
n.(IndirectOperand).hasOperandAndIndirectionIndex(op, _) and
715+
isArgumentOfCallableOperand(call, op)
716+
)
717+
or
718+
exists(Instruction instr |
719+
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(instr, _) and
720+
isArgumentOfCallableInstruction(call, instr)
721+
)
689722
}
690723

691724
/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */

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

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,20 @@ private module IteratorIndirections {
320320
}
321321
}
322322

323-
predicate isDereference(Instruction deref, Operand address) {
324-
any(Indirection ind).isAdditionalDereference(deref, address)
323+
/**
324+
* Holds if `deref` is the result of loading the value at the address
325+
* represented by `address`.
326+
*
327+
* If `additional = true` then the dereference comes from an `Indirection`
328+
* class (such as a call to an iterator's `operator*`), and if
329+
* `additional = false` the dereference is a `LoadInstruction`.
330+
*/
331+
predicate isDereference(Instruction deref, Operand address, boolean additional) {
332+
any(Indirection ind).isAdditionalDereference(deref, address) and
333+
additional = true
325334
or
326-
deref.(LoadInstruction).getSourceAddressOperand() = address
335+
deref.(LoadInstruction).getSourceAddressOperand() = address and
336+
additional = false
327337
}
328338

329339
predicate isWrite(Node0Impl value, Operand address, boolean certain) {
@@ -545,7 +555,7 @@ private module Cached {
545555
isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and
546556
isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and
547557
iteratorBase.getResultType() instanceof Interfaces::Iterator and
548-
isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse()) and
558+
isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and
549559
memory = read.getSideEffectOperand().getAnyDef()
550560
)
551561
}
@@ -781,11 +791,14 @@ private module Cached {
781791
* instead associated with the operand returned by this predicate.
782792
*/
783793
cached
784-
Operand getIRRepresentationOfIndirectOperand(Operand operand, int indirectionIndex) {
794+
predicate hasIRRepresentationOfIndirectOperand(
795+
Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr
796+
) {
797+
indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and
785798
exists(Instruction load |
786-
isDereference(load, operand) and
787-
result = unique( | | getAUse(load)) and
788-
isUseImpl(operand, _, indirectionIndex - 1)
799+
isDereference(load, operand, false) and
800+
operandRepr = unique( | | getAUse(load)) and
801+
indirectionIndexRepr = indirectionIndex - 1
789802
)
790803
}
791804

@@ -797,12 +810,15 @@ private module Cached {
797810
* instead associated with the instruction returned by this predicate.
798811
*/
799812
cached
800-
Instruction getIRRepresentationOfIndirectInstruction(Instruction instr, int indirectionIndex) {
813+
predicate hasIRRepresentationOfIndirectInstruction(
814+
Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr
815+
) {
816+
indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
801817
exists(Instruction load, Operand address |
802818
address.getDef() = instr and
803-
isDereference(load, address) and
804-
isUseImpl(address, _, indirectionIndex - 1) and
805-
result = load
819+
isDereference(load, address, false) and
820+
instrRepr = load and
821+
indirectionIndexRepr = indirectionIndex - 1
806822
)
807823
}
808824

@@ -823,7 +839,7 @@ private module Cached {
823839
or
824840
exists(int ind0 |
825841
exists(Operand address |
826-
isDereference(operand.getDef(), address) and
842+
isDereference(operand.getDef(), address, _) and
827843
isUseImpl(address, base, ind0)
828844
)
829845
or
@@ -893,7 +909,7 @@ private module Cached {
893909
)
894910
or
895911
exists(Operand address, boolean certain0 |
896-
isDereference(operand.getDef(), address) and
912+
isDereference(operand.getDef(), address, _) and
897913
isDefImpl(address, base, ind - 1, certain0)
898914
|
899915
if isCertainAddress(operand) then certain = certain0 else certain = false

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst
5757
)
5858
or
5959
// Taint flow from an address to its dereference.
60-
Ssa::isDereference(instrTo, opFrom)
60+
Ssa::isDereference(instrTo, opFrom, _)
6161
or
6262
// Unary instructions tend to preserve enough information in practice that we
6363
// want taint to flow through.

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,35 @@ edges
99
| test.cpp:22:5:22:7 | arr indirection [p] | test.cpp:19:9:19:16 | mk_array indirection [p] |
1010
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | arr indirection [p] |
1111
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | arr indirection [p] |
12-
| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p indirection |
13-
| test.cpp:31:13:31:13 | p indirection | test.cpp:31:13:31:13 | p |
14-
| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p indirection |
15-
| test.cpp:35:13:35:13 | p indirection | test.cpp:35:13:35:13 | p |
12+
| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p |
13+
| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p |
1614
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | arr indirection [p] |
1715
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | arr indirection [p] |
18-
| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p indirection |
19-
| test.cpp:41:13:41:13 | p indirection | test.cpp:41:13:41:13 | p |
20-
| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p indirection |
21-
| test.cpp:45:13:45:13 | p indirection | test.cpp:45:13:45:13 | p |
16+
| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p |
17+
| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p |
2218
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] |
2319
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:9:55:9 | arr indirection [post update] [p] |
2420
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | test.cpp:56:5:56:7 | arr indirection [p] |
2521
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... |
2622
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:59:9:59:11 | arr indirection [p] |
2723
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:63:9:63:11 | arr indirection [p] |
28-
| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p indirection |
29-
| test.cpp:59:13:59:13 | p indirection | test.cpp:59:13:59:13 | p |
30-
| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p indirection |
31-
| test.cpp:63:13:63:13 | p indirection | test.cpp:63:13:63:13 | p |
24+
| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p |
25+
| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p |
3226
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] |
3327
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] |
3428
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:10:69:10 | arr indirection [post update] [p] |
3529
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
3630
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
3731
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
32+
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] |
3833
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
3934
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
40-
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p indirection |
41-
| test.cpp:79:14:79:14 | p indirection | test.cpp:79:14:79:14 | p |
42-
| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p indirection |
43-
| test.cpp:83:14:83:14 | p indirection | test.cpp:83:14:83:14 | p |
35+
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |
36+
| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p |
4437
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:89:9:89:11 | arr indirection [p] |
4538
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:93:9:93:11 | arr indirection [p] |
46-
| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p indirection |
47-
| test.cpp:89:14:89:14 | p indirection | test.cpp:89:14:89:14 | p |
48-
| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p indirection |
49-
| test.cpp:93:14:93:14 | p indirection | test.cpp:93:14:93:14 | p |
39+
| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p |
40+
| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p |
5041
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | test.cpp:87:28:87:30 | arr indirection [p] |
5142
nodes
5243
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
@@ -60,28 +51,22 @@ nodes
6051
| test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] |
6152
| test.cpp:31:9:31:11 | arr indirection [p] | semmle.label | arr indirection [p] |
6253
| test.cpp:31:13:31:13 | p | semmle.label | p |
63-
| test.cpp:31:13:31:13 | p indirection | semmle.label | p indirection |
6454
| test.cpp:35:9:35:11 | arr indirection [p] | semmle.label | arr indirection [p] |
6555
| test.cpp:35:13:35:13 | p | semmle.label | p |
66-
| test.cpp:35:13:35:13 | p indirection | semmle.label | p indirection |
6756
| test.cpp:39:27:39:29 | arr [p] | semmle.label | arr [p] |
6857
| test.cpp:41:9:41:11 | arr indirection [p] | semmle.label | arr indirection [p] |
6958
| test.cpp:41:13:41:13 | p | semmle.label | p |
70-
| test.cpp:41:13:41:13 | p indirection | semmle.label | p indirection |
7159
| test.cpp:45:9:45:11 | arr indirection [p] | semmle.label | arr indirection [p] |
7260
| test.cpp:45:13:45:13 | p | semmle.label | p |
73-
| test.cpp:45:13:45:13 | p indirection | semmle.label | p indirection |
7461
| test.cpp:50:18:50:25 | call to mk_array [p] | semmle.label | call to mk_array [p] |
7562
| test.cpp:55:5:55:24 | ... = ... | semmle.label | ... = ... |
7663
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
7764
| test.cpp:55:13:55:18 | call to malloc | semmle.label | call to malloc |
7865
| test.cpp:56:5:56:7 | arr indirection [p] | semmle.label | arr indirection [p] |
7966
| test.cpp:59:9:59:11 | arr indirection [p] | semmle.label | arr indirection [p] |
8067
| test.cpp:59:13:59:13 | p | semmle.label | p |
81-
| test.cpp:59:13:59:13 | p indirection | semmle.label | p indirection |
8268
| test.cpp:63:9:63:11 | arr indirection [p] | semmle.label | arr indirection [p] |
8369
| test.cpp:63:13:63:13 | p | semmle.label | p |
84-
| test.cpp:63:13:63:13 | p indirection | semmle.label | p indirection |
8570
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | semmle.label | mk_array_p indirection [p] |
8671
| test.cpp:69:5:69:25 | ... = ... | semmle.label | ... = ... |
8772
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
@@ -90,17 +75,13 @@ nodes
9075
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
9176
| test.cpp:79:9:79:11 | arr indirection [p] | semmle.label | arr indirection [p] |
9277
| test.cpp:79:14:79:14 | p | semmle.label | p |
93-
| test.cpp:79:14:79:14 | p indirection | semmle.label | p indirection |
9478
| test.cpp:83:9:83:11 | arr indirection [p] | semmle.label | arr indirection [p] |
9579
| test.cpp:83:14:83:14 | p | semmle.label | p |
96-
| test.cpp:83:14:83:14 | p indirection | semmle.label | p indirection |
9780
| test.cpp:87:28:87:30 | arr indirection [p] | semmle.label | arr indirection [p] |
9881
| test.cpp:89:9:89:11 | arr indirection [p] | semmle.label | arr indirection [p] |
9982
| test.cpp:89:14:89:14 | p | semmle.label | p |
100-
| test.cpp:89:14:89:14 | p indirection | semmle.label | p indirection |
10183
| test.cpp:93:9:93:11 | arr indirection [p] | semmle.label | arr indirection [p] |
10284
| test.cpp:93:14:93:14 | p | semmle.label | p |
103-
| test.cpp:93:14:93:14 | p indirection | semmle.label | p indirection |
10485
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
10586
subpaths
10687
#select
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace {
2+
struct Foo {
3+
char string[10];
4+
};
5+
6+
void acquire(char*);
7+
8+
Foo* test_self_argument_flow() {
9+
Foo *info;
10+
acquire(info->string); // clean
11+
12+
return info;
13+
}
14+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
testFailures
2+
failures
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import cpp
2+
import semmle.code.cpp.dataflow.new.DataFlow
3+
import TestUtilities.InlineExpectationsTest
4+
5+
module TestConfig implements DataFlow::ConfigSig {
6+
predicate isSource(DataFlow::Node source) {
7+
source.getLocation().getFile().getBaseName() = "self_argument_flow.cpp" and
8+
source.asDefiningArgument() =
9+
any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
10+
}
11+
12+
predicate isSink(DataFlow::Node sink) {
13+
sink.asIndirectArgument() = any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
14+
}
15+
}
16+
17+
import DataFlow::Global<TestConfig>
18+
19+
module TestSelfArgumentFlow implements TestSig {
20+
string getARelevantTag() { result = "self-arg-flow" }
21+
22+
predicate hasActualResult(Location location, string element, string tag, string value) {
23+
exists(DataFlow::Node sink |
24+
flowTo(sink) and
25+
location = sink.getLocation() and
26+
element = sink.toString() and
27+
tag = "self-arg-flow" and
28+
value = ""
29+
)
30+
}
31+
}
32+
33+
import MakeTest<TestSelfArgumentFlow>

cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
| ref.cpp:120:17:120:18 | x3 | ref.cpp:129:10:129:11 | x3 |
1515
| ref.cpp:120:21:120:22 | x4 | ref.cpp:131:15:131:16 | x4 |
1616
| ref.cpp:120:21:120:22 | x4 | ref.cpp:132:10:132:11 | x4 |
17+
| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:10:13:10:16 | info |
18+
| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:12:12:12:15 | info |
1719
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
1820
| test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 |
1921
| test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 |

0 commit comments

Comments
 (0)