diff --git a/CMakeLists.txt b/CMakeLists.txt index e1383a9..9856596 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,8 +122,9 @@ if (ARBUTILS_TESTS) target_compile_definitions(ArbutilsTests PRIVATE TESTS_BUILD) if (SANITIZER_TESTS AND NOT WINDOWS) - target_compile_options(ArbutilsTests PRIVATE -fsanitize=address) - target_link_options(ArbutilsTests PRIVATE -fsanitize=address) + message(STATUS "Sanitizers included") + 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 () diff --git a/src/Collections/List.hpp b/src/Collections/List.hpp index 453f6c0..b8702c7 100644 --- a/src/Collections/List.hpp +++ b/src/Collections/List.hpp @@ -1,5 +1,6 @@ #ifndef ARBUTILS_LIST_HPP #define ARBUTILS_LIST_HPP +#include #include #include #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. /// @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. - inline size_t IndexOf(const ValueT& value) const noexcept { + inline std::optional IndexOf(const ValueT& value) const noexcept { const auto& it = std::find(_vector.begin(), _vector.end(), value); if (it == _vector.end()) - return -1; + return {}; return std::distance(_vector.begin(), it); } diff --git a/src/Enum.hpp b/src/Enum.hpp index 50d8afe..1a9a690 100644 --- a/src/Enum.hpp +++ b/src/Enum.hpp @@ -44,17 +44,26 @@ 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...) \ enum class name : type { \ MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \ }; \ class name##Helper { \ + ALLOW_UINTEGER_OVERFLOW \ inline static uint32_t constexpr ConstHash(char const* input) noexcept { \ return *input ? static_cast(*input) + 33 * ConstHash(input + 1) : 5381; \ } \ inline static constexpr char charToLower(const char c) noexcept { \ return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \ } \ + ALLOW_UINTEGER_OVERFLOW \ inline static uint32_t constexpr ConstHashCI(char const* input) noexcept { \ return charToLower(*input) ? static_cast(charToLower(*input)) + 33 * ConstHashCI(input + 1) \ : 5381; \ diff --git a/src/Random.hpp b/src/Random.hpp index a15ed8c..272c289 100644 --- a/src/Random.hpp +++ b/src/Random.hpp @@ -3,10 +3,21 @@ #include #include -#include #include #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 + +#if defined(__clang__) +#pragma clang attribute pop +#endif + + namespace ArbUt { /// @brief A helper class for getting random numbers. /// @tparam RandomT A type for the desired random number generator. @@ -32,13 +43,19 @@ namespace ArbUt { inline RandomT& GetRandomEngine() noexcept { return _rng; } /// @brief Gets a random float between 0.0 and 1.0. - [[nodiscard]] inline constexpr float GetFloat() noexcept { return static_cast(GetDouble()); } + [[nodiscard]] inline constexpr float GetFloat() noexcept { + return static_cast(GetDouble()); + } /// @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 - [[nodiscard]] inline constexpr int32_t Get() noexcept { return static_cast(_rng()); } + inline constexpr int32_t Get() noexcept { + return static_cast(_rng()); + } /// @brief Gets a random 32 bit integer between 0, and given max parameter. /// @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. - [[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. @@ -89,4 +108,6 @@ namespace ArbUt { explicit constexpr Random(uint_fast32_t seed) noexcept : BaseRandom(seed) {} }; } + + #endif // ARBUTILS_RANDOM_HPP diff --git a/tests/ListTests.cpp b/tests/ListTests.cpp index b400fbd..1ffcaaa 100644 --- a/tests/ListTests.cpp +++ b/tests/ListTests.cpp @@ -64,12 +64,11 @@ TEST_CASE("Test IndexOf") { CHECK(ls.IndexOf(5) == 0); CHECK(ls.IndexOf(1500) == 2); CHECK(ls.IndexOf(300) == 5); - CHECK(ls.IndexOf(684) == -1); + CHECK_FALSE(ls.IndexOf(684).has_value()); } TEST_CASE("Test list out of bounds") { auto ls = List({5, 200, 1500, -500, 5, 300, -500}); - REQUIRE_THROWS(ls.At(-1)); REQUIRE_THROWS(ls.At(7)); } diff --git a/tests/UniquePtrListTests.cpp b/tests/UniquePtrListTests.cpp index 4f95c6c..77ef2c3 100644 --- a/tests/UniquePtrListTests.cpp +++ b/tests/UniquePtrListTests.cpp @@ -47,7 +47,6 @@ TEST_CASE("Test unique ptr list out of bounds") { auto v2 = new uint32_t(5000); ls.Append(v1); ls.Append(v2); - REQUIRE_THROWS(ls.At(-1)); REQUIRE_THROWS(ls.At(2)); }