11#include < mutex>
22#include < thread>
33
4+ std::mutex *m4 = new std::mutex(); // NON_COMPLIANT
5+ std::mutex m5; // COMPLIANT
6+ std::mutex *m6 = new std::mutex(); // COMPLIANT
7+
48void t1 (int i, std::mutex *pm) {}
59void t2 (int i, std::mutex **pm) {}
610void t3 (int i, std::mutex *pm) { delete pm; }
11+ void t4 (int i) { delete m4; }
12+ void t5 (int i) { std::lock_guard<std::mutex> lk (m5); }
713
814void f1 () {
915 std::thread threads[5 ];
@@ -16,7 +22,7 @@ void f1() {
1622
1723void f2 () {
1824 std::thread threads[5 ];
19- std::mutex m1; // COMPLIANT - due to check below
25+ std::mutex m1; // COMPLIANT
2026
2127 for (int i = 0 ; i < 5 ; ++i) {
2228 threads[i] = std::thread (t1, i, &m1);
@@ -27,7 +33,8 @@ void f2() {
2733 }
2834}
2935
30- std::mutex m2; // COMPLIANT - since m2 will not go out of scope.
36+ std::mutex m2; // COMPLIANT - m2 is not deleted and never goes out of scope.
37+ // There is no delete
3138
3239void f3 () {
3340 std::thread threads[5 ];
@@ -106,4 +113,34 @@ void f9() {
106113 std::mutex m; // COMPLIANT
107114}
108115
109- std::mutex *m4 = new std::mutex(); // COMPLIANT
116+ // f10 does not wait but it is OK since m5 is global and doesn't go out of
117+ // scope -- the destructor isn't called until the program exists.
118+ void f10 () {
119+ std::thread threads[5 ];
120+
121+ for (int i = 0 ; i < 5 ; ++i) {
122+ threads[i] = std::thread (t5, i);
123+ }
124+ }
125+
126+ // f11 represents an invalid usage of the global mutex `m4` since it attempts to
127+ // delete it from within the thread.
128+ void f11 () {
129+ std::thread threads[5 ];
130+
131+ for (int i = 0 ; i < 5 ; ++i) {
132+ threads[i] = std::thread (t4, i);
133+ }
134+ }
135+
136+ // f12 represents a valid but tricky usage of the global mutex `m6` since it is
137+ // not deleted/accessed from the thread
138+ void f12 () {
139+ std::thread threads[5 ];
140+
141+ for (int i = 0 ; i < 5 ; ++i) {
142+ threads[i] = std::thread (t4, i);
143+ }
144+
145+ delete m6;
146+ }
0 commit comments