Skip to content

Commit 1dc0894

Browse files
committed
C++: Use 'MustFlow' in 'cpp/uninitialized-local'.
1 parent a17cd9b commit 1dc0894

File tree

2 files changed

+32
-49
lines changed

2 files changed

+32
-49
lines changed

cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
*/
1414

1515
import cpp
16-
import semmle.code.cpp.controlflow.StackVariableReachability
16+
import semmle.code.cpp.ir.IR
17+
import semmle.code.cpp.ir.dataflow.MustFlow
1718

1819
/**
1920
* Auxiliary predicate: Types that don't require initialization
@@ -33,31 +34,6 @@ predicate allocatedType(Type t) {
3334
allocatedType(t.getUnspecifiedType())
3435
}
3536

36-
/**
37-
* A declaration of a local variable that leaves the
38-
* variable uninitialized.
39-
*/
40-
DeclStmt declWithNoInit(LocalVariable v) {
41-
result.getADeclaration() = v and
42-
not exists(v.getInitializer()) and
43-
/* The type of the variable is not stack-allocated. */
44-
exists(Type t | t = v.getType() | not allocatedType(t))
45-
}
46-
47-
class UninitialisedLocalReachability extends StackVariableReachability {
48-
UninitialisedLocalReachability() { this = "UninitialisedLocal" }
49-
50-
override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
51-
52-
override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVarActual(v, node) }
53-
54-
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
55-
// only report the _first_ possibly uninitialized use
56-
useOfVarActual(v, node) or
57-
definitionBarrier(v, node)
58-
}
59-
}
60-
6137
pragma[noinline]
6238
predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
6339

@@ -82,8 +58,31 @@ VariableAccess commonException() {
8258
containsInlineAssembly(result.getEnclosingFunction())
8359
}
8460

85-
from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va
61+
predicate isSinkImpl(Instruction sink, VariableAccess va) {
62+
exists(LoadInstruction load |
63+
va = load.getUnconvertedResultExpression() and
64+
not va = commonException() and
65+
sink = load.getSourceValue()
66+
)
67+
}
68+
69+
class MustFlow extends MustFlowConfiguration {
70+
MustFlow() { this = "MustFlow" }
71+
72+
override predicate isSource(Instruction source) {
73+
source instanceof UninitializedInstruction and
74+
exists(Type t | t = source.getResultType() | not allocatedType(t))
75+
}
76+
77+
override predicate isSink(Operand sink) { isSinkImpl(sink.getDef(), _) }
78+
79+
override predicate allowInterproceduralFlow() { none() }
80+
}
81+
82+
from
83+
VariableAccess va, LocalVariable v, MustFlow conf, MustFlowPathNode source, MustFlowPathNode sink
8684
where
87-
r.reaches(_, v, va) and
88-
not va = commonException()
85+
conf.hasFlowPath(source, sink) and
86+
isSinkImpl(sink.getInstruction(), va) and
87+
v = va.getTarget()
8988
select va, "The variable $@ may not be initialized at this access.", v, v.getName()
Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,4 @@
1-
| test.cpp:12:6:12:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
2-
| test.cpp:30:6:30:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:26:6:26:8 | foo | foo |
3-
| test.cpp:46:6:46:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:42:6:42:8 | foo | foo |
4-
| test.cpp:55:7:55:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:50:6:50:8 | foo | foo |
5-
| test.cpp:67:7:67:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:61:6:61:8 | foo | foo |
6-
| test.cpp:92:6:92:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:82:6:82:8 | foo | foo |
7-
| test.cpp:113:6:113:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
8-
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized at this access. | test.cpp:126:6:126:6 | j | j |
9-
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized at this access. | test.cpp:218:7:218:7 | x | x |
10-
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized at this access. | test.cpp:241:6:241:6 | i | i |
11-
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized at this access. | test.cpp:321:6:321:8 | val | val |
12-
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized at this access. | test.cpp:333:7:333:7 | a | a |
13-
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized at this access. | test.cpp:358:7:358:7 | a | a |
14-
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized at this access. | test.cpp:359:6:359:8 | val | val |
15-
| test.cpp:417:10:417:10 | j | The variable $@ may not be initialized at this access. | test.cpp:414:9:414:9 | j | j |
16-
| test.cpp:436:9:436:9 | j | The variable $@ may not be initialized at this access. | test.cpp:431:9:431:9 | j | j |
17-
| test.cpp:454:2:454:2 | x | The variable $@ may not be initialized at this access. | test.cpp:452:6:452:6 | x | x |
18-
| test.cpp:460:7:460:7 | x | The variable $@ may not be initialized at this access. | test.cpp:458:6:458:6 | x | x |
19-
| test.cpp:467:2:467:2 | x | The variable $@ may not be initialized at this access. | test.cpp:464:6:464:6 | x | x |
20-
| test.cpp:474:7:474:7 | x | The variable $@ may not be initialized at this access. | test.cpp:471:6:471:6 | x | x |
1+
| test.cpp:121:6:121:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:119:6:119:8 | foo | foo |
2+
| test.cpp:179:7:179:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:177:7:177:9 | foo | foo |
3+
| test.cpp:192:7:192:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:190:7:190:9 | foo | foo |
4+
| test.cpp:213:7:213:7 | x | The variable $@ may not be initialized at this access. | test.cpp:211:7:211:7 | x | x |

0 commit comments

Comments
 (0)