More sanitizers, fixes several errors caught by these.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
6005850115
commit
afd51a7924
|
@ -122,8 +122,9 @@ if (ARBUTILS_TESTS)
|
||||||
target_compile_definitions(ArbutilsTests PRIVATE TESTS_BUILD)
|
target_compile_definitions(ArbutilsTests PRIVATE TESTS_BUILD)
|
||||||
|
|
||||||
if (SANITIZER_TESTS AND NOT WINDOWS)
|
if (SANITIZER_TESTS AND NOT WINDOWS)
|
||||||
target_compile_options(ArbutilsTests PRIVATE -fsanitize=address)
|
message(STATUS "Sanitizers included")
|
||||||
target_link_options(ArbutilsTests PRIVATE -fsanitize=address)
|
target_compile_options(ArbutilsTests PRIVATE -fsanitize=address,undefined,leak,integer,nullability -fno-sanitize-recover=all )
|
||||||
|
target_link_options(ArbutilsTests PRIVATE -fsanitize=address,undefined,leak,integer,nullability -fno-sanitize-recover=all )
|
||||||
endif()
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef ARBUTILS_LIST_HPP
|
#ifndef ARBUTILS_LIST_HPP
|
||||||
#define ARBUTILS_LIST_HPP
|
#define ARBUTILS_LIST_HPP
|
||||||
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../Exception.hpp"
|
#include "../Exception.hpp"
|
||||||
|
@ -88,10 +89,10 @@ namespace ArbUt {
|
||||||
/// @brief Find the index of the first occurrence of a value in the list, return -1 if none is found.
|
/// @brief Find the index of the first occurrence of a value in the list, return -1 if none is found.
|
||||||
/// @param value The value we want the index for.
|
/// @param value The value we want the index for.
|
||||||
/// @return The index of the first occurrence of the value in the list, or -1 if none is found.
|
/// @return The index of the first occurrence of the value in the list, or -1 if none is found.
|
||||||
inline size_t IndexOf(const ValueT& value) const noexcept {
|
inline std::optional<size_t> IndexOf(const ValueT& value) const noexcept {
|
||||||
const auto& it = std::find(_vector.begin(), _vector.end(), value);
|
const auto& it = std::find(_vector.begin(), _vector.end(), value);
|
||||||
if (it == _vector.end())
|
if (it == _vector.end())
|
||||||
return -1;
|
return {};
|
||||||
return std::distance(_vector.begin(), it);
|
return std::distance(_vector.begin(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,17 +44,26 @@
|
||||||
static methods for use with the enum.
|
static methods for use with the enum.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#define ALLOW_UINTEGER_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||||
|
#else
|
||||||
|
#define ALLOW_INTEGER_OVERFLOW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define ENUM_WITH_START_VALUE(name, type, startValue, values...) \
|
#define ENUM_WITH_START_VALUE(name, type, startValue, values...) \
|
||||||
enum class name : type { \
|
enum class name : type { \
|
||||||
MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \
|
MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \
|
||||||
}; \
|
}; \
|
||||||
class name##Helper { \
|
class name##Helper { \
|
||||||
|
ALLOW_UINTEGER_OVERFLOW \
|
||||||
inline static uint32_t constexpr ConstHash(char const* input) noexcept { \
|
inline static uint32_t constexpr ConstHash(char const* input) noexcept { \
|
||||||
return *input ? static_cast<uint32_t>(*input) + 33 * ConstHash(input + 1) : 5381; \
|
return *input ? static_cast<uint32_t>(*input) + 33 * ConstHash(input + 1) : 5381; \
|
||||||
} \
|
} \
|
||||||
inline static constexpr char charToLower(const char c) noexcept { \
|
inline static constexpr char charToLower(const char c) noexcept { \
|
||||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \
|
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \
|
||||||
} \
|
} \
|
||||||
|
ALLOW_UINTEGER_OVERFLOW \
|
||||||
inline static uint32_t constexpr ConstHashCI(char const* input) noexcept { \
|
inline static uint32_t constexpr ConstHashCI(char const* input) noexcept { \
|
||||||
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * ConstHashCI(input + 1) \
|
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * ConstHashCI(input + 1) \
|
||||||
: 5381; \
|
: 5381; \
|
||||||
|
|
|
@ -3,10 +3,21 @@
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <pcg_random.hpp>
|
|
||||||
#include <random>
|
#include <random>
|
||||||
#include "Ensure.hpp"
|
#include "Ensure.hpp"
|
||||||
|
|
||||||
|
// PCG uses unsigned shifts, and overflows a lot. Disable the sanitizer for that.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang attribute push (__attribute__((no_sanitize("unsigned-shift-base", "unsigned-integer-overflow"))), apply_to=function)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pcg_random.hpp>
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang attribute pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace ArbUt {
|
namespace ArbUt {
|
||||||
/// @brief A helper class for getting random numbers.
|
/// @brief A helper class for getting random numbers.
|
||||||
/// @tparam RandomT A type for the desired random number generator.
|
/// @tparam RandomT A type for the desired random number generator.
|
||||||
|
@ -32,13 +43,19 @@ namespace ArbUt {
|
||||||
inline RandomT& GetRandomEngine() noexcept { return _rng; }
|
inline RandomT& GetRandomEngine() noexcept { return _rng; }
|
||||||
|
|
||||||
/// @brief Gets a random float between 0.0 and 1.0.
|
/// @brief Gets a random float between 0.0 and 1.0.
|
||||||
[[nodiscard]] inline constexpr float GetFloat() noexcept { return static_cast<float>(GetDouble()); }
|
[[nodiscard]] inline constexpr float GetFloat() noexcept {
|
||||||
|
return static_cast<float>(GetDouble());
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Gets a random double between 0.0 and 1.0.
|
/// @brief Gets a random double between 0.0 and 1.0.
|
||||||
[[nodiscard]] inline constexpr double GetDouble() noexcept { return _distribution(_rng); }
|
[[nodiscard]] inline constexpr double GetDouble() noexcept {
|
||||||
|
return _distribution(_rng);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Gets a random 32 bit integer
|
/// @brief Gets a random 32 bit integer
|
||||||
[[nodiscard]] inline constexpr int32_t Get() noexcept { return static_cast<int32_t>(_rng()); }
|
inline constexpr int32_t Get() noexcept {
|
||||||
|
return static_cast<int32_t>(_rng());
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Gets a random 32 bit integer between 0, and given max parameter.
|
/// @brief Gets a random 32 bit integer between 0, and given max parameter.
|
||||||
/// @param max The exclusive max value the random value should be.
|
/// @param max The exclusive max value the random value should be.
|
||||||
|
@ -77,7 +94,9 @@ namespace ArbUt {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief The seed the random class is generating from.
|
/// @brief The seed the random class is generating from.
|
||||||
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { return _seed; }
|
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept {
|
||||||
|
return _seed;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Implementation of the BaseRandom class with pcg32 as random number generator.
|
/// @brief Implementation of the BaseRandom class with pcg32 as random number generator.
|
||||||
|
@ -89,4 +108,6 @@ namespace ArbUt {
|
||||||
explicit constexpr Random(uint_fast32_t seed) noexcept : BaseRandom(seed) {}
|
explicit constexpr Random(uint_fast32_t seed) noexcept : BaseRandom(seed) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // ARBUTILS_RANDOM_HPP
|
#endif // ARBUTILS_RANDOM_HPP
|
||||||
|
|
|
@ -64,12 +64,11 @@ TEST_CASE("Test IndexOf") {
|
||||||
CHECK(ls.IndexOf(5) == 0);
|
CHECK(ls.IndexOf(5) == 0);
|
||||||
CHECK(ls.IndexOf(1500) == 2);
|
CHECK(ls.IndexOf(1500) == 2);
|
||||||
CHECK(ls.IndexOf(300) == 5);
|
CHECK(ls.IndexOf(300) == 5);
|
||||||
CHECK(ls.IndexOf(684) == -1);
|
CHECK_FALSE(ls.IndexOf(684).has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test list out of bounds") {
|
TEST_CASE("Test list out of bounds") {
|
||||||
auto ls = List<int>({5, 200, 1500, -500, 5, 300, -500});
|
auto ls = List<int>({5, 200, 1500, -500, 5, 300, -500});
|
||||||
REQUIRE_THROWS(ls.At(-1));
|
|
||||||
REQUIRE_THROWS(ls.At(7));
|
REQUIRE_THROWS(ls.At(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ TEST_CASE("Test unique ptr list out of bounds") {
|
||||||
auto v2 = new uint32_t(5000);
|
auto v2 = new uint32_t(5000);
|
||||||
ls.Append(v1);
|
ls.Append(v1);
|
||||||
ls.Append(v2);
|
ls.Append(v2);
|
||||||
REQUIRE_THROWS(ls.At(-1));
|
|
||||||
REQUIRE_THROWS(ls.At(2));
|
REQUIRE_THROWS(ls.At(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue