Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/rfl/Timestamp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
33 changes: 18 additions & 15 deletions include/rfl/Tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include <algorithm>
#include <array>
#include <bit>
#include <cstdint>
#include <limits>
#include <memory>
#include <optional>
#include <stdexcept>
#include <tuple>
Expand Down Expand Up @@ -55,17 +57,16 @@ class Tuple {

/// Gets an element by index.
template <int _index>
auto& get() {
constexpr auto& get() {
using Type = internal::nth_element_t<_index, Types...>;
return *std::launder(reinterpret_cast<Type*>(data_.data() + pos<_index>()));
return *std::bit_cast<Type*>(data_.data() + pos<_index>());
}

/// Gets an element by index.
template <int _index>
const auto& get() const {
constexpr const auto& get() const {
using Type = internal::nth_element_t<_index, Types...>;
return *std::launder(
reinterpret_cast<const Type*>(data_.data() + pos<_index>()));
return *std::bit_cast<const Type*>(data_.data() + pos<_index>());
}

/// Assigns the underlying object.
Expand Down Expand Up @@ -132,7 +133,8 @@ class Tuple {
const auto copy_one = [this]<int _i>(const auto& _other,
std::integral_constant<int, _i>) {
using Type = internal::nth_element_t<_i, Types...>;
new (data_.data() + pos<_i>()) Type(_other.template get<_i>());
::new (static_cast<void*>(data_.data() + pos<_i>()))
Type(_other.template get<_i>());
};
(copy_one(_other, std::integral_constant<int, _is>{}), ...);
}
Expand All @@ -143,7 +145,7 @@ class Tuple {
const auto copy_one = [this]<int _i>(const auto& _t,
std::integral_constant<int, _i>) {
using Type = internal::nth_element_t<_i, Types...>;
new (data_.data() + pos<_i>()) Type(_t);
::new (static_cast<void*>(data_.data() + pos<_i>())) Type(_t);
};
(copy_one(_types, std::integral_constant<int, _is>{}), ...);
}
Expand All @@ -165,7 +167,8 @@ class Tuple {
const auto move_one = [this]<int _i>(auto&& _other,
std::integral_constant<int, _i>) {
using Type = internal::nth_element_t<_i, Types...>;
new (data_.data() + pos<_i>()) Type(std::move(_other.template get<_i>()));
::new (static_cast<void*>(data_.data() + pos<_i>()))
Type(std::move(_other.template get<_i>()));
};
(move_one(_other, std::integral_constant<int, _is>{}), ...);
}
Expand All @@ -175,7 +178,7 @@ class Tuple {
const auto move_one = [this]<int _i>(auto&& _t,
std::integral_constant<int, _i>) {
using Type = internal::nth_element_t<_i, Types...>;
new (data_.data() + pos<_i>()) Type(std::move(_t));
::new (static_cast<void*>(data_.data() + pos<_i>())) Type(std::move(_t));
};
(move_one(std::move(_types), std::integral_constant<int, _is>{}), ...);
}
Expand All @@ -192,25 +195,25 @@ class Tuple {

/// Gets an element by index.
template <int _index, class... Types>
auto& get(rfl::Tuple<Types...>& _tup) {
constexpr auto& get(rfl::Tuple<Types...>& _tup) {
return _tup.template get<_index>();
}

/// Gets an element by index.
template <int _index, class... Types>
const auto& get(const rfl::Tuple<Types...>& _tup) {
constexpr const auto& get(const rfl::Tuple<Types...>& _tup) {
return _tup.template get<_index>();
}

/// Gets an element by index.
template <int _index, class... Types>
auto& get(std::tuple<Types...>& _tup) {
constexpr auto& get(std::tuple<Types...>& _tup) {
return std::get<_index>(_tup);
}

/// Gets an element by index.
template <int _index, class... Types>
const auto& get(const std::tuple<Types...>& _tup) {
constexpr const auto& get(const std::tuple<Types...>& _tup) {
return std::get<_index>(_tup);
}

Expand Down Expand Up @@ -259,13 +262,13 @@ namespace std {

/// Gets an element by index.
template <int _index, class... Types>
auto& get(rfl::Tuple<Types...>& _tup) {
constexpr auto& get(rfl::Tuple<Types...>& _tup) {
return _tup.template get<_index>();
}

/// Gets an element by index.
template <int _index, class... Types>
const auto& get(const rfl::Tuple<Types...>& _tup) {
constexpr const auto& get(const rfl::Tuple<Types...>& _tup) {
return _tup.template get<_index>();
}

Expand Down
4 changes: 2 additions & 2 deletions include/rfl/generic/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }

Expand Down
4 changes: 2 additions & 2 deletions include/rfl/internal/tuple/calculate_positions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ struct Positions {
};

template <class T, unsigned long _last, unsigned long... _is>
consteval auto operator+(const Positions<_last, _is...>& _sizes,
const PositionWrapper<T>& _w) {
consteval auto operator+(const Positions<_last, _is...>&,
const PositionWrapper<T>&) {
if constexpr (_last % alignof(T) == 0) {
constexpr auto last_new = _last + sizeof(T);
return Positions<last_new, _is..., _last>{};
Expand Down
5 changes: 3 additions & 2 deletions include/rfl/internal/tuple/concat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ auto wrap_tuple(const rfl::Tuple<Types...>& _tuple) {

template <class... Types>
auto wrap_tuple(rfl::Tuple<Types...>&& _tuple) {
return TupleWrapper<Types...>{std::move(_tuple)};
return TupleWrapper<Types...>{std::forward<rfl::Tuple<Types...> >(_tuple)};
}

template <class... Types1, class... Types2, int... _is, int... _js>
Expand All @@ -46,7 +46,8 @@ auto concat(const Head& _head, const Tail&... _tail) {

template <class Head, class... Tail>
auto concat(Head&& _head, Tail&&... _tail) {
return (wrap_tuple(std::move(_head)) + ... + wrap_tuple(std::move(_tail)))
return (wrap_tuple(std::forward<Head>(_head)) + ... +
wrap_tuple(std::forward<Tail>(_tail)))
.tuple_;
}

Expand Down
3 changes: 2 additions & 1 deletion include/rfl/tuple_cat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ auto tuple_cat(const Head& _head, const Tail&... _tail) {

template <class Head, class... Tail>
auto tuple_cat(Head&& _head, Tail&&... _tail) {
return internal::tuple::concat(std::move(_head), std::move(_tail)...);
return internal::tuple::concat(std::forward<Head>(_head),
std::forward<Tail>(_tail)...);
}

inline auto tuple_cat() { return rfl::Tuple(); }
Expand Down
3 changes: 2 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
29 changes: 29 additions & 0 deletions tests/json/test_segfault.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <iostream>
#include <rfl.hpp>
#include <rfl/json.hpp>
#include <string>
#include <vector>

#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
Loading