// RUN: %check_clang_tidy %s bugprone-spuriously-wake-up-functions %t -- -- #define NULL 0 namespace std { using intmax_t = int; template class ratio { public: static constexpr intmax_t num = 0; static constexpr intmax_t den = 0; typedef ratio type; }; typedef ratio<1, 1000> milli; namespace chrono { template > class duration { public: using rep = Rep; using period = Period; public: constexpr duration() = default; template constexpr explicit duration(const Rep2 &r); template constexpr duration(const duration &d); ~duration() = default; duration(const duration &) = default; }; template class time_point { public: using clock = Clock; using duration = Duration; public: constexpr time_point(); constexpr explicit time_point(const duration &d); template constexpr time_point(const time_point &t); }; using milliseconds = duration; class system_clock { public: typedef milliseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static time_point now() noexcept; }; } // namespace chrono class mutex; template class unique_lock { public: typedef Mutex mutex_type; unique_lock() noexcept; explicit unique_lock(mutex_type &m); }; class mutex { public: constexpr mutex() noexcept; ~mutex(); mutex(const mutex &) = delete; mutex &operator=(const mutex &) = delete; }; enum class cv_status { no_timeout, timeout }; class condition_variable { public: condition_variable(); ~condition_variable(); condition_variable(const condition_variable &) = delete; void wait(unique_lock &lock); template void wait(unique_lock &lock, Predicate pred); template cv_status wait_until(unique_lock &lock, const chrono::time_point &abs_time){}; template bool wait_until(unique_lock &lock, const chrono::time_point &abs_time, Predicate pred){}; template cv_status wait_for(unique_lock &lock, const chrono::duration &rel_time){}; template bool wait_for(unique_lock &lock, const chrono::duration &rel_time, Predicate pred){}; }; } // namespace std struct Node1 { void *Node1; struct Node1 *next; }; static Node1 list; static std::mutex m; static std::condition_variable condition; void consume_list_element(std::condition_variable &condition) { std::unique_lock lk(m); if (list.next == nullptr) { condition.wait(lk); // 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] } while (list.next == nullptr) { condition.wait(lk); } do { condition.wait(lk); } while (list.next == nullptr); for (;; list.next == nullptr) { condition.wait(lk); } if (list.next == nullptr) { while (list.next == nullptr) { condition.wait(lk); } } if (list.next == nullptr) { do { condition.wait(lk); } while (list.next == nullptr); } if (list.next == nullptr) { for (;; list.next == nullptr) { condition.wait(lk); } } using durtype = std::chrono::duration; durtype dur = std::chrono::duration(); if (list.next == nullptr) { condition.wait_for(lk, dur); // 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] } if (list.next == nullptr) { condition.wait_for(lk, dur, [] { return 1; }); } while (list.next == nullptr) { condition.wait_for(lk, dur); } do { condition.wait_for(lk, dur); } while (list.next == nullptr); for (;; list.next == nullptr) { condition.wait_for(lk, dur); } auto now = std::chrono::system_clock::now(); if (list.next == nullptr) { condition.wait_until(lk, now); // 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] } if (list.next == nullptr) { condition.wait_until(lk, now, [] { return 1; }); } while (list.next == nullptr) { condition.wait_until(lk, now); } do { condition.wait_until(lk, now); } while (list.next == nullptr); for (;; list.next == nullptr) { condition.wait_until(lk, now); } }