Skip to content

Commit 546fc3b

Browse files
committed
refactoring
1 parent baeb6c5 commit 546fc3b

File tree

5 files changed

+101
-2
lines changed

5 files changed

+101
-2
lines changed

cpp/common/src/codingstandards/cpp/Concurrency.qll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,12 @@ class LockProtectedControlFlowNode extends ThreadedCFN {
421421
/**
422422
* Models a function that conditionally waits.
423423
*/
424-
class ConditionalWait extends FunctionCall {
425-
ConditionalWait() {
424+
abstract class ConditionalWait extends FunctionCall {}
425+
/**
426+
* Models a function in CPP that will conditionally wait.
427+
*/
428+
class CPPConditionalWait extends ConditionalWait {
429+
CPPConditionalWait() {
426430
exists(MemberFunction mf |
427431
mf = getTarget() and
428432
mf.getDeclaringType().hasQualifiedName("std", "condition_variable") and
@@ -431,6 +435,15 @@ class ConditionalWait extends FunctionCall {
431435
}
432436
}
433437

438+
/**
439+
* Models a function in C that will conditionally wait.
440+
*/
441+
class CConditionalWait extends ConditionalWait {
442+
CConditionalWait() {
443+
getTarget().getName() in ["cnd_wait"]
444+
}
445+
}
446+
434447
/**
435448
* Models a call to a `std::thread` constructor that depends on a mutex.
436449
*/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Provides a library which includes a `problems` predicate for reporting
3+
* functions that should be wrapped in a loop because they may wake up spuriously.
4+
*/
5+
6+
import cpp
7+
import codingstandards.cpp.Customizations
8+
import codingstandards.cpp.Exclusions
9+
import codingstandards.cpp.Concurrency
10+
11+
abstract class WrapSpuriousFunctionInLoopSharedQuery extends Query { }
12+
13+
Query getQuery() { result instanceof WrapSpuriousFunctionInLoopSharedQuery }
14+
15+
query predicate problems(ConditionalWait cw, string message) {
16+
not isExcluded(cw, getQuery()) and
17+
not cw.getEnclosingStmt().getParentStmt*() instanceof Loop and
18+
message = "Use of a function that may wake up spuriously without a controlling loop."
19+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.cpp:11:8:11:11 | call to wait | Use of a function that may wake up spuriously without a controlling loop. |
2+
| test.cpp:49:6:49:9 | call to wait | Use of a function that may wake up spuriously without a controlling loop. |
3+
| test.cpp:59:8:59:11 | call to wait | Use of a function that may wake up spuriously without a controlling loop. |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.wrapspuriousfunctioninloop.WrapSpuriousFunctionInLoop
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <condition_variable>
2+
#include <mutex>
3+
4+
static std::mutex mu;
5+
static std::condition_variable cv;
6+
7+
void f1() {
8+
std::unique_lock<std::mutex> lk(mu);
9+
10+
if (1) {
11+
cv.wait(lk); // NON_COMPLIANT
12+
}
13+
}
14+
15+
void f2() {
16+
std::unique_lock<std::mutex> lk(mu);
17+
int i = 2;
18+
while (i > 0) {
19+
cv.wait(lk); // COMPLIANT
20+
i--;
21+
}
22+
}
23+
24+
void f3() {
25+
std::unique_lock<std::mutex> lk(mu);
26+
int i = 2;
27+
do {
28+
cv.wait(lk); // COMPLIANT
29+
i--;
30+
} while (i > 0);
31+
}
32+
33+
void f4() {
34+
std::unique_lock<std::mutex> lk(mu);
35+
36+
for (;;) {
37+
cv.wait(lk); // COMPLIANT
38+
}
39+
}
40+
41+
void f5() {
42+
std::unique_lock<std::mutex> lk(mu);
43+
44+
int i = 2;
45+
while (i > 0) {
46+
i--;
47+
}
48+
49+
cv.wait(lk); // NON_COMPLIANT
50+
}
51+
52+
void f6() {
53+
std::unique_lock<std::mutex> lk(mu);
54+
55+
for (int i = 0; i < 10; i++) {
56+
}
57+
int i = 0;
58+
if (i > 0) {
59+
cv.wait(lk); // NON_COMPLIANT
60+
i--;
61+
}
62+
}

0 commit comments

Comments
 (0)