File tree Expand file tree Collapse file tree 5 files changed +101
-2
lines changed
rules/wrapspuriousfunctioninloop
test/rules/wrapspuriousfunctioninloop Expand file tree Collapse file tree 5 files changed +101
-2
lines changed Original file line number Diff line number Diff line change @@ -421,8 +421,12 @@ class LockProtectedControlFlowNode extends ThreadedCFN {
421
421
/**
422
422
* Models a function that conditionally waits.
423
423
*/
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 ( ) {
426
430
exists ( MemberFunction mf |
427
431
mf = getTarget ( ) and
428
432
mf .getDeclaringType ( ) .hasQualifiedName ( "std" , "condition_variable" ) and
@@ -431,6 +435,15 @@ class ConditionalWait extends FunctionCall {
431
435
}
432
436
}
433
437
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
+
434
447
/**
435
448
* Models a call to a `std::thread` constructor that depends on a mutex.
436
449
*/
Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change
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. |
Original file line number Diff line number Diff line change
1
+ // GENERATED FILE - DO NOT MODIFY
2
+ import codingstandards.cpp.rules.wrapspuriousfunctioninloop.WrapSpuriousFunctionInLoop
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments