diff --git a/include/rfl/Timestamp.hpp b/include/rfl/Timestamp.hpp index fd9dcfa6..16f53f44 100644 --- a/include/rfl/Timestamp.hpp +++ b/include/rfl/Timestamp.hpp @@ -25,6 +25,8 @@ class Timestamp { using ReflectionType = std::string; + Timestamp() : tm_(std::tm{}) {} + Timestamp(const char* _str) : tm_(std::tm{}) { const auto r = strptime(_str, _format.str().c_str(), &tm_); if (r == NULL) { diff --git a/include/rfl/Tuple.hpp b/include/rfl/Tuple.hpp index 43ab91d4..85e38bc4 100644 --- a/include/rfl/Tuple.hpp +++ b/include/rfl/Tuple.hpp @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -55,17 +57,16 @@ class Tuple { /// Gets an element by index. template - auto& get() { + constexpr auto& get() { using Type = internal::nth_element_t<_index, Types...>; - return *std::launder(reinterpret_cast(data_.data() + pos<_index>())); + return *std::bit_cast(data_.data() + pos<_index>()); } /// Gets an element by index. template - const auto& get() const { + constexpr const auto& get() const { using Type = internal::nth_element_t<_index, Types...>; - return *std::launder( - reinterpret_cast(data_.data() + pos<_index>())); + return *std::bit_cast(data_.data() + pos<_index>()); } /// Assigns the underlying object. @@ -132,7 +133,8 @@ class Tuple { const auto copy_one = [this](const auto& _other, std::integral_constant) { using Type = internal::nth_element_t<_i, Types...>; - new (data_.data() + pos<_i>()) Type(_other.template get<_i>()); + ::new (static_cast(data_.data() + pos<_i>())) + Type(_other.template get<_i>()); }; (copy_one(_other, std::integral_constant{}), ...); } @@ -143,7 +145,7 @@ class Tuple { const auto copy_one = [this](const auto& _t, std::integral_constant) { using Type = internal::nth_element_t<_i, Types...>; - new (data_.data() + pos<_i>()) Type(_t); + ::new (static_cast(data_.data() + pos<_i>())) Type(_t); }; (copy_one(_types, std::integral_constant{}), ...); } @@ -165,7 +167,8 @@ class Tuple { const auto move_one = [this](auto&& _other, std::integral_constant) { using Type = internal::nth_element_t<_i, Types...>; - new (data_.data() + pos<_i>()) Type(std::move(_other.template get<_i>())); + ::new (static_cast(data_.data() + pos<_i>())) + Type(std::move(_other.template get<_i>())); }; (move_one(_other, std::integral_constant{}), ...); } @@ -175,7 +178,7 @@ class Tuple { const auto move_one = [this](auto&& _t, std::integral_constant) { using Type = internal::nth_element_t<_i, Types...>; - new (data_.data() + pos<_i>()) Type(std::move(_t)); + ::new (static_cast(data_.data() + pos<_i>())) Type(std::move(_t)); }; (move_one(std::move(_types), std::integral_constant{}), ...); } @@ -192,25 +195,25 @@ class Tuple { /// Gets an element by index. template -auto& get(rfl::Tuple& _tup) { +constexpr auto& get(rfl::Tuple& _tup) { return _tup.template get<_index>(); } /// Gets an element by index. template -const auto& get(const rfl::Tuple& _tup) { +constexpr const auto& get(const rfl::Tuple& _tup) { return _tup.template get<_index>(); } /// Gets an element by index. template -auto& get(std::tuple& _tup) { +constexpr auto& get(std::tuple& _tup) { return std::get<_index>(_tup); } /// Gets an element by index. template -const auto& get(const std::tuple& _tup) { +constexpr const auto& get(const std::tuple& _tup) { return std::get<_index>(_tup); } @@ -259,13 +262,13 @@ namespace std { /// Gets an element by index. template -auto& get(rfl::Tuple& _tup) { +constexpr auto& get(rfl::Tuple& _tup) { return _tup.template get<_index>(); } /// Gets an element by index. template -const auto& get(const rfl::Tuple& _tup) { +constexpr const auto& get(const rfl::Tuple& _tup) { return _tup.template get<_index>(); } diff --git a/include/rfl/generic/Writer.hpp b/include/rfl/generic/Writer.hpp index 98ffabd7..b4e72027 100644 --- a/include/rfl/generic/Writer.hpp +++ b/include/rfl/generic/Writer.hpp @@ -85,9 +85,9 @@ struct Writer { OutputVarType add_null_to_object(const std::string_view& _name, OutputObjectType* _parent) const noexcept; - void end_array(OutputArrayType* _arr) const noexcept {} + void end_array(OutputArrayType*) const noexcept {} - void end_object(OutputObjectType* _obj) const noexcept {} + void end_object(OutputObjectType*) const noexcept {} OutputVarType& root() { return root_; } diff --git a/include/rfl/internal/tuple/calculate_positions.hpp b/include/rfl/internal/tuple/calculate_positions.hpp index 1b884336..20e375b9 100644 --- a/include/rfl/internal/tuple/calculate_positions.hpp +++ b/include/rfl/internal/tuple/calculate_positions.hpp @@ -17,8 +17,8 @@ struct Positions { }; template -consteval auto operator+(const Positions<_last, _is...>& _sizes, - const PositionWrapper& _w) { +consteval auto operator+(const Positions<_last, _is...>&, + const PositionWrapper&) { if constexpr (_last % alignof(T) == 0) { constexpr auto last_new = _last + sizeof(T); return Positions{}; diff --git a/include/rfl/internal/tuple/concat.hpp b/include/rfl/internal/tuple/concat.hpp index 7d441ad3..3020a000 100644 --- a/include/rfl/internal/tuple/concat.hpp +++ b/include/rfl/internal/tuple/concat.hpp @@ -19,7 +19,7 @@ auto wrap_tuple(const rfl::Tuple& _tuple) { template auto wrap_tuple(rfl::Tuple&& _tuple) { - return TupleWrapper{std::move(_tuple)}; + return TupleWrapper{std::forward >(_tuple)}; } template @@ -46,7 +46,8 @@ auto concat(const Head& _head, const Tail&... _tail) { template auto concat(Head&& _head, Tail&&... _tail) { - return (wrap_tuple(std::move(_head)) + ... + wrap_tuple(std::move(_tail))) + return (wrap_tuple(std::forward(_head)) + ... + + wrap_tuple(std::forward(_tail))) .tuple_; } diff --git a/include/rfl/tuple_cat.hpp b/include/rfl/tuple_cat.hpp index 8c0ab2cd..da558f54 100644 --- a/include/rfl/tuple_cat.hpp +++ b/include/rfl/tuple_cat.hpp @@ -13,7 +13,8 @@ auto tuple_cat(const Head& _head, const Tail&... _tail) { template auto tuple_cat(Head&& _head, Tail&&... _tail) { - return internal::tuple::concat(std::move(_head), std::move(_tail)...); + return internal::tuple::concat(std::forward(_head), + std::forward(_tail)...); } inline auto tuple_cat() { return rfl::Tuple(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index edcc9808..ef908c0c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,7 +3,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2") if (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std:c++20") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Wno-sign-compare -Wno-missing-braces -Wno-psabi -pthread -fno-strict-aliasing -fwrapv -O2 -ftemplate-backtrace-limit=0 -fsanitize=undefined") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Wno-sign-compare -Wno-missing-braces -Wno-psabi -pthread -fno-strict-aliasing -fwrapv -O3 -ftemplate-backtrace-limit=0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -ggdb -ftemplate-backtrace-limit=0") endif() if (REFLECTCPP_JSON) diff --git a/tests/json/test_segfault.cpp b/tests/json/test_segfault.cpp new file mode 100644 index 00000000..cd2ce656 --- /dev/null +++ b/tests/json/test_segfault.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +#include "write_and_read.hpp" + +// This example had led to a segfault on GCC 12. +// To make sure this won't happen again, we include +// it in our tests. +namespace test_segfault { + +struct Data { + std::string prop1; + std::string prop2; + std::string prop3; + std::string prop4; + std::string prop5; + std::string prop6; +}; + +TEST(json, test_segfault) { + const auto data = Data{}; + write_and_read( + data, + R"({"prop1":"","prop2":"","prop3":"","prop4":"","prop5":"","prop6":""})"); +} +} // namespace test_segfault