Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dae8162

Browse filesBrowse files
Address feedback
1 parent e1a0d6d commit dae8162
Copy full SHA for dae8162

15 files changed

+140
-92
lines changed

‎c/common/src/codingstandards/c/SubObjects.qll

Copy file name to clipboardExpand all lines: c/common/src/codingstandards/c/SubObjects.qll
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
/**
2+
* A library that expands upon the `Objects.qll` library, to support nested "Objects" such as
3+
* `x.y.z` or `x[i][j]` within an object `x`.
4+
*
5+
* Objects in C are values in memory, that have a type and a storage duration. In the case of
6+
* array objects and struct objects, the object will contain other objects. The these subobjects
7+
* will share properties of the root object such as storage duration. This library can be used to,
8+
* for instance, find all usages of a struct member to ensure that member is initialized before it
9+
* is used.
10+
*
11+
* To use this library, select `SubObject` and find its usages in the AST via `getAnAccess()` (to
12+
* find usages of the subobject by value) or `getAnAddressOfExpr()` (to find usages of the object
13+
* by address).
14+
*
15+
* Note that a struct or array object may contain a pointer. In this case, the pointer itself is
16+
* a subobject of the struct or array object, but the object that the pointer points to is not.
17+
* This is because the pointed-to object does not necessarily have the same storage duration,
18+
* lifetime, or linkage as the pointer and the object containing the pointer.
19+
*
20+
* Note as well that `getAnAccess()` on an array subobject will return all accesses to the array,
21+
* not just accesses to a particular index. For this reason, `SubObject` exposes the predicate
22+
* `isPrecise()`. If a subobject is precise, that means all results of `getAnAccess()` will
23+
* definitely refer to the same object in memory. If it is not precise, the different accesses
24+
* may refer to the same or different objects in memory. For instance, `x[i].y` and `x[j].y` are
25+
* the same object if `i` and `j` are the same, but they are different objects if `i` and `j` are
26+
* different.
27+
*/
28+
129
import codingstandards.c.Objects
230

331
newtype TSubObject =
@@ -70,6 +98,8 @@ class SubObject extends TSubObject {
7098
exists(MemberVariable m |
7199
this = TObjectMember(_, m) and
72100
result = m.getAnAccess() and
101+
// Only consider `DotFieldAccess`es, not `PointerFieldAccess`es, as the latter
102+
// are not subobjects of the root object:
73103
result.(DotFieldAccess).getQualifier() = getParent().getAnAccess()
74104
)
75105
or
@@ -79,6 +109,11 @@ class SubObject extends TSubObject {
79109

80110
AddressOfExpr getAnAddressOfExpr() { result.getOperand() = this.getAnAccess() }
81111

112+
/**
113+
* Get the "root" object identity to which this subobject belongs. For instance, in the
114+
* expression `x.y.z`, the root object is `x`. This subobject will share properties with the root
115+
* object such as storage duration, lifetime, and linkage.
116+
*/
82117
ObjectIdentity getRootIdentity() {
83118
exists(ObjectIdentity i |
84119
this = TObjectRoot(i) and

‎c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll

Copy file name to clipboardExpand all lines: c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ signature module GlobalInitializationAnalysisConfigSig {
77
/** A function which is not called or started as a thread */
88
default predicate isRootFunction(Function f) {
99
not exists(Function f2 | f2.calls(f)) and
10-
not f instanceof ThreadedFunction
10+
not f instanceof ThreadedFunction and
11+
// Exclude functions which are used as function pointers.
12+
not exists(FunctionAccess access | f = access.getTarget())
1113
}
1214

1315
ObjectIdentity getAnInitializedObject(Expr e);

‎c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql
+22-18Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class NonReentrantOperation extends TNonReentrantOperation {
4747
)
4848
}
4949

50-
Expr getARead() {
50+
Expr getAReadExpr() {
5151
exists(SubObject object |
5252
this = TReadWrite(object) and
5353
result = object.getAnAccess()
@@ -56,7 +56,7 @@ class NonReentrantOperation extends TNonReentrantOperation {
5656
this = TStdFunctionCall(result)
5757
}
5858

59-
Expr getAWrite() {
59+
Expr getAWriteExpr() {
6060
exists(SubObject object, Assignment assignment |
6161
this = TReadWrite(object) and
6262
result = assignment and
@@ -94,39 +94,43 @@ class NonReentrantOperation extends TNonReentrantOperation {
9494

9595
class WritingThread extends ThreadedFunction {
9696
NonReentrantOperation aWriteObject;
97-
Expr aWrite;
97+
Expr aWriteExpr;
9898

9999
WritingThread() {
100-
aWrite = aWriteObject.getAWrite() and
101-
this.calls*(aWrite.getEnclosingFunction()) and
102-
not aWrite instanceof LockProtectedControlFlowNode and
103-
not aWrite.getEnclosingFunction().getName().matches(["%init%", "%boot%", "%start%"])
100+
aWriteExpr = aWriteObject.getAWriteExpr() and
101+
// This function directly contains the write expression, or transitively calls the function
102+
// that contains the write expression.
103+
this.calls*(aWriteExpr.getEnclosingFunction()) and
104+
// The write isn't synchronized with a mutex or condition object.
105+
not aWriteExpr instanceof LockProtectedControlFlowNode and
106+
// The write doesn't seem to be during a special initialization phase of the program.
107+
not aWriteExpr.getEnclosingFunction().getName().matches(["%init%", "%boot%", "%start%"])
104108
}
105109

106-
Expr getAWrite() { result = aWrite }
110+
Expr getAWriteExpr() { result = aWriteExpr }
107111
}
108112

109113
class ReadingThread extends ThreadedFunction {
110114
Expr aReadExpr;
111115

112116
ReadingThread() {
113117
exists(NonReentrantOperation op |
114-
aReadExpr = op.getARead() and
118+
aReadExpr = op.getAReadExpr() and
115119
this.calls*(aReadExpr.getEnclosingFunction()) and
116120
not aReadExpr instanceof LockProtectedControlFlowNode
117121
)
118122
}
119123

120-
Expr getARead() { result = aReadExpr }
124+
Expr getAReadExpr() { result = aReadExpr }
121125
}
122126

123127
predicate mayBeDataRace(Expr write, Expr read, NonReentrantOperation operation) {
124128
exists(WritingThread wt |
125-
wt.getAWrite() = write and
126-
write = operation.getAWrite() and
129+
wt.getAWriteExpr() = write and
130+
write = operation.getAWriteExpr() and
127131
exists(ReadingThread rt |
128-
read = rt.getARead() and
129-
read = operation.getARead() and
132+
read = rt.getAReadExpr() and
133+
read = operation.getAReadExpr() and
130134
(
131135
wt.isMultiplySpawned() or
132136
not wt = rt
@@ -141,18 +145,18 @@ from
141145
where
142146
not isExcluded(write, Concurrency9Package::possibleDataRaceBetweenThreadsQuery()) and
143147
mayBeDataRace(write, read, operation) and
144-
wt = min(WritingThread f | f.getAWrite() = write | f order by f.getName()) and
145-
rt = min(ReadingThread f | f.getARead() = read | f order by f.getName()) and
148+
wt = min(WritingThread f | f.getAWriteExpr() = write | f order by f.getName()) and
149+
rt = min(ReadingThread f | f.getAReadExpr() = read | f order by f.getName()) and
146150
writeString = operation.getWriteString() and
147151
readString = operation.getReadString() and
148152
if wt.isMultiplySpawned()
149153
then
150154
message =
151155
"Threaded " + writeString +
152-
" $@ not synchronized, for example from thread function $@ spawned from a loop."
156+
" $@ not synchronized from thread function $@ spawned from a loop."
153157
else
154158
message =
155159
"Threaded " + writeString +
156-
" $@, for example from thread function $@, not synchronized with $@, for example from thread function $@."
160+
" $@ from thread function $@ is not synchronized with $@ from thread function $@."
157161
select write, message, operation.getSourceElement(), operation.toString(), wt, wt.getName(), read,
158162
"concurrent " + readString, rt, rt.getName()

‎c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ where
6464
not isExcluded(operation, Concurrency9Package::invalidOperationOnUnlockedMutexQuery()) and
6565
mutex = operation.getMutex() and
6666
not DominatingSet::isDominatedByBehavior(operation)
67-
select operation, "Invalid operation on mutex '$@' not locked by the current thread",
67+
select operation, "Invalid operation on mutex '$@' not locked by the current thread.",
6868
mutex.getRootIdentity(), mutex.toString()

‎c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @id c/misra/non-recursive-mutex-recursively-locked-audit
33
* @name RULE-22-18: (Audit) Non-recursive mutexes shall not be recursively locked
44
* @description Mutex that may be initialized without mtx_recursive shall not be locked by a thread
5-
* that has previous may havec locked it.
5+
* that may have previously locked it.
66
* @kind problem
77
* @precision high
88
* @problem.severity error
@@ -57,4 +57,4 @@ where
5757
isTrackableMutex(lockCall, true) or
5858
isTrackableMutex(coveredByLock, true)
5959
)
60-
select n, "Mutex locked after previous $@.", coveredByLock, "already locked"
60+
select n, "Mutex locked after it was already $@.", coveredByLock, "previously locked"

‎c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ where
6464
useOne = firstCallForConditionMutex(cond, mutexOne) and
6565
useTwo = firstCallForConditionMutex(cond, mutexOne)
6666
select useOne,
67-
"Condition variable $@ associated with multiple mutexes, operation uses mutex $@ while $@ uses other mutex $@",
67+
"Condition variable $@ associated with multiple mutexes, operation uses mutex $@ while $@ uses other mutex $@.",
6868
cond.getRootIdentity(), cond.toString(), mutexOne.getRootIdentity(), mutexOne.toString(), useTwo,
6969
"another operation", mutexTwo.getRootIdentity(), mutexTwo.toString()

‎c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ where
4040
not isExcluded(objUse, Concurrency9Package::threadStorageNotInitializedBeforeUseQuery()) and
4141
InitAnalysis::uninitializedFrom(objUse, obj, callRoot)
4242
select objUse,
43-
"Thread specific storage pointer '$@' possibly used before initialization, from entry point function '$@'.",
43+
"Thread specific storage pointer '$@' used before initialization from entry point function '$@'.",
4444
obj, obj.toString(), callRoot, callRoot.getName()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.