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