Skip to content

Commit

Permalink
Added rudimentary fuzzer
Browse files Browse the repository at this point in the history
  • Loading branch information
martinus committed Jul 12, 2022
1 parent 871629f commit 451de39
Show file tree
Hide file tree
Showing 8 changed files with 643 additions and 3 deletions.
4 changes: 3 additions & 1 deletion include/ankerl/unordered_dense.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,9 @@ class table {
}

void clear_buckets() {
std::memset(m_buckets_start, 0, sizeof(Bucket) * bucket_count());
if (m_buckets_start != nullptr) {
std::memset(m_buckets_start, 0, sizeof(Bucket) * bucket_count());
}
}

void clear_and_fill_buckets_from_values() {
Expand Down
2 changes: 1 addition & 1 deletion scripts/lint/lint-clang-format.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
f"{root_path}/test/**/*.h",
f"{root_path}/test/**/*.cpp",
]
exclusions = ["nanobench\.h"]
exclusions = ["nanobench\.h", "FuzzedDataProvider\.h"]

files = []
for g in globs:
Expand Down
32 changes: 31 additions & 1 deletion test/app/Counter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,43 @@
#include <stdexcept>
#include <unordered_set>

#define COUNTER_ENABLE_UNORDERED_SET 0

#if COUNTER_ENABLE_UNORDERED_SET
auto singletonConstructedObjects() -> std::unordered_set<Counter::Obj const*>& {
static std::unordered_set<Counter::Obj const*> data{};
return data;
}
#endif

Counter::Obj::Obj()
: mData(0)
, mCounts(nullptr) {
#if COUNTER_ENABLE_UNORDERED_SET
if (!singletonConstructedObjects().emplace(this).second) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
++staticDefaultCtor;
}

Counter::Obj::Obj(const size_t& data, Counter& counts)
: mData(data)
, mCounts(&counts) {
#if COUNTER_ENABLE_UNORDERED_SET
if (!singletonConstructedObjects().emplace(this).second) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
++mCounts->ctor;
}

Counter::Obj::Obj(const Counter::Obj& o)
: mData(o.mData)
, mCounts(o.mCounts) {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
Expand All @@ -43,6 +52,7 @@ Counter::Obj::Obj(const Counter::Obj& o)
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != mCounts) {
++mCounts->copyCtor;
}
Expand All @@ -51,6 +61,7 @@ Counter::Obj::Obj(const Counter::Obj& o)
Counter::Obj::Obj(Counter::Obj&& o) noexcept
: mData(o.mData)
, mCounts(o.mCounts) {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
Expand All @@ -59,16 +70,19 @@ Counter::Obj::Obj(Counter::Obj&& o) noexcept
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != mCounts) {
++mCounts->moveCtor;
}
}

Counter::Obj::~Obj() {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().erase(this)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != mCounts) {
++mCounts->dtor;
} else {
Expand All @@ -77,21 +91,25 @@ Counter::Obj::~Obj() {
}

auto Counter::Obj::operator==(const Counter::Obj& o) const -> bool {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(this) || 1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != mCounts) {
++mCounts->equals;
}
return mData == o.mData;
}

auto Counter::Obj::operator<(const Obj& o) const -> bool {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(this) || 1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != mCounts) {
++mCounts->less;
}
Expand All @@ -100,10 +118,12 @@ auto Counter::Obj::operator<(const Obj& o) const -> bool {

// NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
auto Counter::Obj::operator=(const Counter::Obj& o) -> Counter::Obj& {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(this) || 1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
mCounts = o.mCounts;
if (nullptr != mCounts) {
++mCounts->assign;
Expand All @@ -113,10 +133,12 @@ auto Counter::Obj::operator=(const Counter::Obj& o) -> Counter::Obj& {
}

auto Counter::Obj::operator=(Counter::Obj&& o) noexcept -> Counter::Obj& {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(this) || 1 != singletonConstructedObjects().count(&o)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
if (nullptr != o.mCounts) {
mCounts = o.mCounts;
}
Expand All @@ -142,10 +164,12 @@ auto Counter::Obj::get() -> size_t& {
}

void Counter::Obj::swap(Obj& other) {
#if COUNTER_ENABLE_UNORDERED_SET
if (1 != singletonConstructedObjects().count(this) || 1 != singletonConstructedObjects().count(&other)) {
test::print("ERROR at {}({}): {}\n", __FILE__, __LINE__, __func__);
std::abort();
}
#endif
using std::swap;
swap(mData, other.mData);
swap(mCounts, other.mCounts);
Expand All @@ -166,7 +190,8 @@ Counter::Counter() {
Counter::staticDtor = 0;
}

Counter::~Counter() {
void Counter::check_all_done() const {
#if COUNTER_ENABLE_UNORDERED_SET
// check that all are destructed
if (!singletonConstructedObjects().empty()) {
test::print("ERROR at ~Counter(): got {} objects still alive!", singletonConstructedObjects().size());
Expand All @@ -176,6 +201,11 @@ Counter::~Counter() {
test::print("ERROR at ~Counter(): number of counts does not match!");
std::abort();
}
#endif
}

Counter::~Counter() {
check_all_done();
}

auto Counter::total() const -> size_t {
Expand Down
2 changes: 2 additions & 0 deletions test/app/Counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct Counter {
Counter();
~Counter();

void check_all_done() const;

size_t ctor{};
size_t defaultCtor{};
size_t copyCtor{};
Expand Down
73 changes: 73 additions & 0 deletions test/fuzz/Fuzz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once

#include "FuzzedDataProvider.h"

class Fuzz {
FuzzedDataProvider m_fdp;

public:
inline explicit Fuzz(uint8_t const* data, size_t size)
: m_fdp(data, size) {}

// random number in inclusive range [min, max]
template <typename T>
auto range(T min, T max) -> T {
return m_fdp.ConsumeIntegralInRange(min, max);
}

template <typename T>
auto integral() -> T {
return m_fdp.ConsumeIntegral<T>();
}

template <typename... Args>
auto pick(Args&&... args) -> std::common_type_t<decltype(args)...>& {
static constexpr auto num_ops = sizeof...(args);

auto idx = size_t{};
auto const chosen_idx = m_fdp.ConsumeIntegralInRange<size_t>(0, num_ops - 1);
std::common_type_t<decltype(args)...>* result = nullptr;
((idx++ == chosen_idx ? (result = &args, true) : false) || ...);
return *result;
}

template <typename... Ops>
void loop_call_any(Ops&&... op) {
static constexpr auto num_ops = sizeof...(op);

do {
if constexpr (num_ops == 1) {
(op(), ...);
} else {
auto chosen_op_idx = range<size_t>(0, num_ops - 1);
auto op_idx = size_t{};
((op_idx++ == chosen_op_idx ? op() : void()), ...);
}
} while (0 != m_fdp.remaining_bytes());
}

template <typename... Ops>
void limited_loop_call_any(size_t min, size_t max, Ops&&... op) {
static constexpr auto num_ops = sizeof...(op);

size_t const num_evaluations = m_fdp.ConsumeIntegralInRange(min, max);
for (size_t i = 0; i < num_evaluations; ++i) {
if constexpr (num_ops == 1) {
(op(), ...);
} else {
auto chosen_op_idx = range<size_t>(0, num_ops - 1);
auto op_idx = size_t{};
((op_idx++ == chosen_op_idx ? op() : void()), ...);
}
if (m_fdp.remaining_bytes() == 0) {
return;
}
}
}

static inline void require(bool b) {
if (!b) {
__builtin_trap();
}
}
};
Loading

0 comments on commit 451de39

Please sign in to comment.