|
| 1 | +import TestBase |
1 | 2 | import TestUtilities.dataflow.FlowTestCommon |
2 | | - |
3 | | -module AstTest { |
4 | | - private import semmle.code.cpp.dataflow.DataFlow |
5 | | - private import semmle.code.cpp.controlflow.Guards |
6 | | - |
7 | | - /** |
8 | | - * A `BarrierGuard` that stops flow to all occurrences of `x` within statement |
9 | | - * S in `if (guarded(x)) S`. |
10 | | - */ |
11 | | - // This is tested in `BarrierGuard.cpp`. |
12 | | - predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) { |
13 | | - g.(FunctionCall).getTarget().getName() = "guarded" and |
14 | | - checked = g.(FunctionCall).getArgument(0) and |
15 | | - isTrue = true |
16 | | - } |
17 | | - |
18 | | - /** Common data flow configuration to be used by tests. */ |
19 | | - module AstTestAllocationConfig implements DataFlow::ConfigSig { |
20 | | - predicate isSource(DataFlow::Node source) { |
21 | | - source.asExpr().(FunctionCall).getTarget().getName() = "source" |
22 | | - or |
23 | | - source.asParameter().getName().matches("source%") |
24 | | - or |
25 | | - source.asExpr().(FunctionCall).getTarget().getName() = "indirect_source" |
26 | | - or |
27 | | - source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%") |
28 | | - or |
29 | | - // Track uninitialized variables |
30 | | - exists(source.asUninitialized()) |
31 | | - } |
32 | | - |
33 | | - predicate isSink(DataFlow::Node sink) { |
34 | | - exists(FunctionCall call | |
35 | | - call.getTarget().getName() = ["sink", "indirect_sink"] and |
36 | | - sink.asExpr() = call.getAnArgument() |
37 | | - ) |
38 | | - } |
39 | | - |
40 | | - predicate isBarrier(DataFlow::Node barrier) { |
41 | | - barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or |
42 | | - barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode() |
43 | | - } |
44 | | - } |
45 | | - |
46 | | - module AstFlow = DataFlow::Global<AstTestAllocationConfig>; |
47 | | -} |
48 | | - |
49 | | -module IRTest { |
50 | | - private import cpp |
51 | | - private import semmle.code.cpp.ir.dataflow.DataFlow |
52 | | - private import semmle.code.cpp.ir.IR |
53 | | - private import semmle.code.cpp.controlflow.IRGuards |
54 | | - |
55 | | - /** |
56 | | - * A `BarrierGuard` that stops flow to all occurrences of `x` within statement |
57 | | - * S in `if (guarded(x)) S`. |
58 | | - */ |
59 | | - // This is tested in `BarrierGuard.cpp`. |
60 | | - predicate testBarrierGuard(IRGuardCondition g, Expr checked, boolean isTrue) { |
61 | | - exists(Call call | |
62 | | - call = g.getUnconvertedResultExpression() and |
63 | | - call.getTarget().hasName("guarded") and |
64 | | - checked = call.getArgument(0) and |
65 | | - isTrue = true |
66 | | - ) |
67 | | - } |
68 | | - |
69 | | - /** Common data flow configuration to be used by tests. */ |
70 | | - module IRTestAllocationConfig implements DataFlow::ConfigSig { |
71 | | - predicate isSource(DataFlow::Node source) { |
72 | | - source.asExpr().(FunctionCall).getTarget().getName() = "source" |
73 | | - or |
74 | | - source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source" |
75 | | - or |
76 | | - source.asParameter().getName().matches("source%") |
77 | | - or |
78 | | - source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%") |
79 | | - or |
80 | | - exists(source.asUninitialized()) |
81 | | - } |
82 | | - |
83 | | - predicate isSink(DataFlow::Node sink) { |
84 | | - exists(FunctionCall call, Expr e | e = call.getAnArgument() | |
85 | | - call.getTarget().getName() = "sink" and |
86 | | - sink.asExpr() = e |
87 | | - or |
88 | | - call.getTarget().getName() = "indirect_sink" and |
89 | | - sink.asIndirectExpr() = e |
90 | | - ) |
91 | | - } |
92 | | - |
93 | | - predicate isBarrier(DataFlow::Node barrier) { |
94 | | - exists(Expr barrierExpr | barrierExpr in [barrier.asExpr(), barrier.asIndirectExpr()] | |
95 | | - barrierExpr.(VariableAccess).getTarget().hasName("barrier") |
96 | | - ) |
97 | | - or |
98 | | - barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode() |
99 | | - or |
100 | | - barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getAnIndirectBarrierNode() |
101 | | - } |
102 | | - } |
103 | | - |
104 | | - module IRFlow = DataFlow::Global<IRTestAllocationConfig>; |
105 | | -} |
106 | | - |
107 | 3 | import MakeTest<MergeTests<AstFlowTest<AstTest::AstFlow>, IRFlowTest<IRTest::IRFlow>>> |
0 commit comments