1 | // RUN: %check_clang_tidy %s bugprone-spuriously-wake-up-functions %t -- -- |
2 | #define NULL 0 |
3 | |
4 | namespace std { |
5 | using intmax_t = int; |
6 | |
7 | template <intmax_t N, intmax_t D = 1> |
8 | class ratio { |
9 | public: |
10 | static constexpr intmax_t num = 0; |
11 | static constexpr intmax_t den = 0; |
12 | typedef ratio<num, den> type; |
13 | }; |
14 | typedef ratio<1, 1000> milli; |
15 | namespace chrono { |
16 | |
17 | template <class Rep, class Period = ratio<1>> |
18 | class duration { |
19 | public: |
20 | using rep = Rep; |
21 | using period = Period; |
22 | |
23 | public: |
24 | constexpr duration() = default; |
25 | template <class Rep2> |
26 | constexpr explicit duration(const Rep2 &r); |
27 | template <class Rep2, class Period2> |
28 | constexpr duration(const duration<Rep2, Period2> &d); |
29 | ~duration() = default; |
30 | duration(const duration &) = default; |
31 | }; |
32 | |
33 | template <class Clock, class Duration = typename Clock::duration> |
34 | class time_point { |
35 | public: |
36 | using clock = Clock; |
37 | using duration = Duration; |
38 | |
39 | public: |
40 | constexpr time_point(); |
41 | constexpr explicit time_point(const duration &d); |
42 | template <class Duration2> |
43 | constexpr time_point(const time_point<clock, Duration2> &t); |
44 | }; |
45 | |
46 | using milliseconds = duration<int, milli>; |
47 | |
48 | class system_clock { |
49 | public: |
50 | typedef milliseconds duration; |
51 | typedef duration::rep rep; |
52 | typedef duration::period period; |
53 | typedef chrono::time_point<system_clock> time_point; |
54 | |
55 | static time_point now() noexcept; |
56 | }; |
57 | } // namespace chrono |
58 | |
59 | class mutex; |
60 | template <class Mutex> |
61 | class unique_lock { |
62 | public: |
63 | typedef Mutex mutex_type; |
64 | |
65 | unique_lock() noexcept; |
66 | explicit unique_lock(mutex_type &m); |
67 | }; |
68 | |
69 | class mutex { |
70 | public: |
71 | constexpr mutex() noexcept; |
72 | ~mutex(); |
73 | mutex(const mutex &) = delete; |
74 | mutex &operator=(const mutex &) = delete; |
75 | }; |
76 | |
77 | enum class cv_status { |
78 | no_timeout, |
79 | timeout |
80 | }; |
81 | |
82 | class condition_variable { |
83 | public: |
84 | condition_variable(); |
85 | ~condition_variable(); |
86 | condition_variable(const condition_variable &) = delete; |
87 | |
88 | void wait(unique_lock<mutex> &lock); |
89 | template <class Predicate> |
90 | void wait(unique_lock<mutex> &lock, Predicate pred); |
91 | template <class Clock, class Duration> |
92 | cv_status wait_until(unique_lock<mutex> &lock, |
93 | const chrono::time_point<Clock, Duration> &abs_time){}; |
94 | template <class Clock, class Duration, class Predicate> |
95 | bool wait_until(unique_lock<mutex> &lock, |
96 | const chrono::time_point<Clock, Duration> &abs_time, |
97 | Predicate pred){}; |
98 | template <class Rep, class Period> |
99 | cv_status wait_for(unique_lock<mutex> &lock, |
100 | const chrono::duration<Rep, Period> &rel_time){}; |
101 | template <class Rep, class Period, class Predicate> |
102 | bool wait_for(unique_lock<mutex> &lock, |
103 | const chrono::duration<Rep, Period> &rel_time, |
104 | Predicate pred){}; |
105 | }; |
106 | |
107 | } // namespace std |
108 | |
109 | struct Node1 { |
110 | void *Node1; |
111 | struct Node1 *next; |
112 | }; |
113 | |
114 | static Node1 list; |
115 | static std::mutex m; |
116 | static std::condition_variable condition; |
117 | |
118 | void consume_list_element(std::condition_variable &condition) { |
119 | std::unique_lock<std::mutex> lk(m); |
120 | |
121 | if (list.next == nullptr) { |
122 | condition.wait(lock&: lk); |
123 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions] |
124 | } |
125 | |
126 | while (list.next == nullptr) { |
127 | condition.wait(lock&: lk); |
128 | } |
129 | |
130 | do { |
131 | condition.wait(lock&: lk); |
132 | } while (list.next == nullptr); |
133 | |
134 | for (;; list.next == nullptr) { |
135 | condition.wait(lock&: lk); |
136 | } |
137 | |
138 | if (list.next == nullptr) { |
139 | while (list.next == nullptr) { |
140 | condition.wait(lock&: lk); |
141 | } |
142 | } |
143 | |
144 | if (list.next == nullptr) { |
145 | do { |
146 | condition.wait(lock&: lk); |
147 | } while (list.next == nullptr); |
148 | } |
149 | |
150 | if (list.next == nullptr) { |
151 | for (;; list.next == nullptr) { |
152 | condition.wait(lock&: lk); |
153 | } |
154 | } |
155 | using durtype = std::chrono::duration<int, std::milli>; |
156 | durtype dur = std::chrono::duration<int, std::milli>(); |
157 | if (list.next == nullptr) { |
158 | condition.wait_for(lock&: lk, rel_time: dur); |
159 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait_for' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions] |
160 | } |
161 | if (list.next == nullptr) { |
162 | condition.wait_for(lock&: lk, rel_time: dur, pred: [] { return 1; }); |
163 | } |
164 | while (list.next == nullptr) { |
165 | condition.wait_for(lock&: lk, rel_time: dur); |
166 | } |
167 | do { |
168 | condition.wait_for(lock&: lk, rel_time: dur); |
169 | } while (list.next == nullptr); |
170 | for (;; list.next == nullptr) { |
171 | condition.wait_for(lock&: lk, rel_time: dur); |
172 | } |
173 | |
174 | auto now = std::chrono::system_clock::now(); |
175 | if (list.next == nullptr) { |
176 | condition.wait_until(lock&: lk, abs_time: now); |
177 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait_until' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions] |
178 | } |
179 | if (list.next == nullptr) { |
180 | condition.wait_until(lock&: lk, abs_time: now, pred: [] { return 1; }); |
181 | } |
182 | while (list.next == nullptr) { |
183 | condition.wait_until(lock&: lk, abs_time: now); |
184 | } |
185 | do { |
186 | condition.wait_until(lock&: lk, abs_time: now); |
187 | } while (list.next == nullptr); |
188 | for (;; list.next == nullptr) { |
189 | condition.wait_until(lock&: lk, abs_time: now); |
190 | } |
191 | } |
192 | |