/* * Copyright (c) 2017-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include namespace atomic_test { class A { std::atomic x; public: A() : x(0) {} void add() { ++x; } void sub() { --x; } bool is_zero() const { return x == 0; } }; void is_zero_impossible_npe_ok() { A a; int* p = nullptr; a.add(); a.sub(); if (!a.is_zero()) *p = 42; } void is_zero_possible_npe_bad() { A a; int* p = nullptr; a.add(); a.sub(); if (a.is_zero()) *p = 42; } void not_zero_impossible_npe_ok() { A a; int* p = nullptr; a.add(); a.add(); if (a.is_zero()) *p = 42; } void not_zero_possible_npe_bad() { A a; int* p = nullptr; a.sub(); a.sub(); if (!a.is_zero()) *p = 42; } void load_store_impossible_npe_ok() { std::atomic a(0); int* p = nullptr; a.store(1); if (a.load() != 1) *p = 42; } void load_store_possible_npe_bad() { std::atomic a(0); int* p = nullptr; a.store(1); if (a.load() == 1) *p = 42; } void exchange_impossible_npe_ok() { std::atomic a(0); int* p = nullptr; int b = a.exchange(1); if (a != 1 || b != 0) *p = 42; } void exchange_possible_npe_bad() { std::atomic a(0); int* p = nullptr; int b = a.exchange(1); if (a == 1 && b == 0) *p = 42; } void compare_exchange_weak_impossible_npe1_ok() { std::atomic a(0); int b = 0; int* p = nullptr; int succ = a.compare_exchange_weak(b, 2); if (a != 2 || b != 0 || !succ) *p = 42; } void compare_exchange_weak_possible_npe1_bad() { std::atomic a(0); int b = 0; int* p = nullptr; int succ = a.compare_exchange_weak(b, 2); if (a == 2 && b == 0 && succ) *p = 42; } void compare_exchange_weak_impossible_npe2_ok() { std::atomic a(0); int b = 1; int* p = nullptr; int succ = a.compare_exchange_weak(b, 2); if (a != 0 || b != 0 || succ) *p = 42; } void compare_exchange_weak_possible_npe2_bad() { std::atomic a(0); int b = 1; int* p = nullptr; int succ = a.compare_exchange_weak(b, 2); if (a == 0 && b == 0 && !succ) *p = 42; } void compare_exchange_strong_impossible_npe1_ok() { std::atomic a(0); int b = 0; int* p = nullptr; int succ = a.compare_exchange_strong(b, 2); if (a != 2 || b != 0 || !succ) *p = 42; } void compare_exchange_strong_possible_npe1_bad() { std::atomic a(0); int b = 0; int* p = nullptr; int succ = a.compare_exchange_strong(b, 2); if (a == 2 && b == 0 && succ) *p = 42; } void compare_exchange_strong_impossible_npe2_ok() { std::atomic a(0); int b = 1; int* p = nullptr; int succ = a.compare_exchange_strong(b, 2); if (a != 0 || b != 0 || succ) *p = 42; } void compare_exchange_strong_possible_npe2_bad() { std::atomic a(0); int b = 1; int* p = nullptr; int succ = a.compare_exchange_strong(b, 2); if (a == 0 && b == 0 && !succ) *p = 42; } } // namespace atomic_test