You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
3.1 KiB
163 lines
3.1 KiB
7 years ago
|
/*
|
||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* This source code is licensed under the BSD style license found in the
|
||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||
|
*/
|
||
|
#include <atomic>
|
||
|
|
||
|
namespace atomic_test {
|
||
|
|
||
|
class A {
|
||
|
std::atomic<int> 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<int> a(0);
|
||
|
int* p = nullptr;
|
||
|
a.store(1);
|
||
|
if (a.load() != 1)
|
||
|
*p = 42;
|
||
|
}
|
||
|
|
||
|
void load_store_possible_npe_bad() {
|
||
|
std::atomic<int> a(0);
|
||
|
int* p = nullptr;
|
||
|
a.store(1);
|
||
|
if (a.load() == 1)
|
||
|
*p = 42;
|
||
|
}
|
||
|
|
||
|
void exchange_impossible_npe_ok() {
|
||
|
std::atomic<int> a(0);
|
||
|
int* p = nullptr;
|
||
|
int b = a.exchange(1);
|
||
|
if (a != 1 || b != 0)
|
||
|
*p = 42;
|
||
|
}
|
||
|
|
||
|
void exchange_possible_npe_bad() {
|
||
|
std::atomic<int> 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<int> 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<int> 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<int> 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<int> 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<int> 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<int> 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<int> 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<int> 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
|