-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathGlobalInitializationAnalysis.qll
More file actions
95 lines (81 loc) · 2.95 KB
/
GlobalInitializationAnalysis.qll
File metadata and controls
95 lines (81 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import cpp
import codingstandards.c.Objects
import codingstandards.cpp.Concurrency
import codingstandards.cpp.Type
signature module GlobalInitializationAnalysisConfigSig {
/** A function which is not called or started as a thread */
default predicate isRootFunction(Function f) {
not exists(Function f2 | f2.calls(f)) and
not f instanceof ThreadedFunction and
// Exclude functions which are used as function pointers.
not exists(FunctionAccess access | f = access.getTarget())
}
ObjectIdentity getAnInitializedObject(Expr e);
ObjectIdentity getAUsedObject(Expr e);
}
module GlobalInitalizationAnalysis<GlobalInitializationAnalysisConfigSig Config> {
final class FinalFunction = Function;
final class FinalExpr = Expr;
class RootFunction extends FinalFunction {
RootFunction() { Config::isRootFunction(this) }
}
/** A function call which initializes a mutex or a condition */
class ObjectInit extends FinalExpr {
ObjectIdentity owningObject;
ObjectInit() { owningObject = Config::getAnInitializedObject(this) }
ObjectIdentity getOwningObject() { result = owningObject }
}
/**
* A function argument where that argument is used as a mutex or condition object.
*/
class ObjectUse extends FinalExpr {
ObjectIdentity owningObject;
ObjectUse() { owningObject = Config::getAUsedObject(this) }
ObjectIdentity getOwningObject() { result = owningObject }
}
predicate requiresInitializedMutexObject(
Function func, ObjectUse mutexUse, ObjectIdentity owningObject
) {
mutexUse.getEnclosingFunction() = func and
owningObject = mutexUse.getOwningObject() and
not exists(ObjectInit init |
init.getEnclosingFunction() = func and
init.getOwningObject() = owningObject and
mutexUse.getAPredecessor+() = init
)
or
exists(FunctionCall call |
func = call.getEnclosingFunction() and
requiresInitializedMutexObject(call.getTarget(), mutexUse, owningObject) and
not exists(ObjectInit init |
call.getAPredecessor*() = init and
init.getOwningObject() = owningObject
)
)
or
exists(C11ThreadCreateCall call |
func = call.getEnclosingFunction() and
not owningObject.getStorageDuration().isThread() and
requiresInitializedMutexObject(call.getFunction(), mutexUse, owningObject) and
not exists(ObjectInit init |
call.getAPredecessor*() = init and
init.getOwningObject() = owningObject
)
)
}
predicate uninitializedFrom(Expr e, ObjectIdentity obj, Function callRoot) {
exists(ObjectUse use | use = e |
obj = use.getOwningObject() and
requiresInitializedMutexObject(callRoot, use, obj) and
(
if obj.getStorageDuration().isAutomatic()
then obj.getEnclosingElement+() = callRoot
else (
obj.getStorageDuration().isThread() and callRoot instanceof ThreadedFunction
or
callRoot instanceof RootFunction
)
)
)
}
}