From 85922a3fb8655f86876d1984e5d60eaf812efe31 Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 21 Mar 2022 10:49:47 -0700 Subject: [PATCH 1/4] fix a bunch of warnings --- CMakeLists.txt | 4 ++-- bench/bench-large-pod-search.cpp | 2 +- bench/bench-large-pod.cpp | 2 +- examples/example-partials.cpp | 4 ++-- examples/example-proxy.cpp | 2 +- examples/example-struct-of-arrays.cpp | 17 ++++++----------- include/refl.hpp | 16 ++++++++++++---- test/050-Attributes.hpp | 13 ++++++++++++- test/060-Utils.hpp | 4 ++-- 9 files changed, 39 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e395f5..9825525 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,9 @@ target_include_directories( target_compile_features(refl-cpp INTERFACE cxx_std_17) if (MSVC) - add_compile_options(/W4) + add_compile_options(/W4 /WX) else() - add_compile_options(-Wall -Wextra -pedantic) + add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Wconversion -Werror) endif() # ---- Install ---- diff --git a/bench/bench-large-pod-search.cpp b/bench/bench-large-pod-search.cpp index fe31cd8..aebdf0d 100644 --- a/bench/bench-large-pod-search.cpp +++ b/bench/bench-large-pod-search.cpp @@ -23,7 +23,7 @@ void ProcessClass() { if constexpr (refl::descriptor::is_writable(member)) { - auto reader = refl::descriptor::get_reader(member); + auto reader [[maybe_unused]] = refl::descriptor::get_reader(member); // etc. } else if constexpr (! refl::descriptor::has_writer(member)) diff --git a/bench/bench-large-pod.cpp b/bench/bench-large-pod.cpp index 6a02291..dd371cb 100644 --- a/bench/bench-large-pod.cpp +++ b/bench/bench-large-pod.cpp @@ -20,7 +20,7 @@ void ProcessClass() { if constexpr (refl::descriptor::is_writable(member)) { - auto reader = refl::descriptor::get_reader(member); + auto reader [[maybe_unused]] = refl::descriptor::get_reader(member); // etc. } else if constexpr (! refl::descriptor::has_writer(member)) diff --git a/examples/example-partials.cpp b/examples/example-partials.cpp index e260fc6..57111a8 100644 --- a/examples/example-partials.cpp +++ b/examples/example-partials.cpp @@ -56,7 +56,7 @@ class partial : public refl::runtime::proxy, T> template auto& get() { - constexpr size_t idx = refl::trait::index_of_v; + constexpr auto idx = refl::trait::index_of_v; static_assert(idx != -1); return refl::util::get(data); } @@ -64,7 +64,7 @@ class partial : public refl::runtime::proxy, T> template const auto& get() const { - constexpr size_t idx = refl::trait::index_of_v; + constexpr auto idx = refl::trait::index_of_v; static_assert(idx != -1); return refl::util::get(data); } diff --git a/examples/example-proxy.cpp b/examples/example-proxy.cpp index 7c0945f..f40538e 100644 --- a/examples/example-proxy.cpp +++ b/examples/example-proxy.cpp @@ -99,7 +99,7 @@ using User = value_proxy; int main() { - User user{{ 10 }}; + User user{{ 10, {} }}; assert(user.id() == 10); // user.id(10) // fails with a static assertion (is_writable(member)) diff --git a/examples/example-struct-of-arrays.cpp b/examples/example-struct-of-arrays.cpp index 475337e..1b41122 100644 --- a/examples/example-struct-of-arrays.cpp +++ b/examples/example-struct-of-arrays.cpp @@ -1,6 +1,7 @@ #include "refl.hpp" #include #include +#include /********************************/ template @@ -22,13 +23,13 @@ struct struct_of_arrays : refl::runtime::proxy, std::remove_ using readable_members = readable_member_list>; static_assert(readable_members::size > 0, "Type has no fields!"); - struct_of_arrays(size_t capacity = 4) + struct_of_arrays() { } void push_back(const T& value) { - for_each(readable_members {}, [&](auto member, size_t index) { + for_each(readable_members {}, [&](auto member) { constexpr auto i = refl::trait::index_of_v; std::get(storage_).push_back(member(value)); }); @@ -42,15 +43,6 @@ struct struct_of_arrays : refl::runtime::proxy, std::remove_ }); } - T at(size_t index) const - { - T t{}; - for_each(readable_members{}, [&](auto member) { - constexpr auto i = refl::trait::index_of_v; - std::get(storage_).pop_back(); - }); - } - template auto& operator[](Member) { @@ -164,6 +156,9 @@ int main() std::cout << "size=" << colors.size() << "\n"; for (size_t i = 0; i < colors.size(); i++) { + assert(red_chan[i] == colors.red(i)); + assert(green_chan[i] == colors.green(i)); + assert(blue_chan[i] == colors.blue(i)); std::cout << "r=" << red_chan[i] << ",g=" << green_chan[i] << ",b=" << blue_chan[i] << "\n"; } } diff --git a/include/refl.hpp b/include/refl.hpp index fd51739..d05ab3b 100644 --- a/include/refl.hpp +++ b/include/refl.hpp @@ -58,9 +58,11 @@ namespace std #endif -#ifdef _MSC_VER -// Disable VS warning for "Not enough arguments for macro" -// (emitted when a REFL_ macro is not provided any attributes) +// Disable warnings about non-conformant variadic macros +// There isn't any fix before c++20 +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" +#elif defined(_MSC_VER) #pragma warning( disable : 4003 ) #endif @@ -3181,8 +3183,14 @@ namespace refl [[deprecated]] constexpr auto get_bases(TypeDescriptor t) noexcept { static_assert(trait::is_type_v); +#ifdef __GNUG__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif static_assert(has_bases(t), "Target type does not have a bases attribute."); - +#ifdef __GNUG__ +#pragma GCC diagnostic pop +#endif constexpr auto bases = get_attribute(t); using base_types = typename decltype(bases)::list_type; return trait::map_t{}; diff --git a/test/050-Attributes.hpp b/test/050-Attributes.hpp index 93b3974..ae066c8 100644 --- a/test/050-Attributes.hpp +++ b/test/050-Attributes.hpp @@ -103,9 +103,20 @@ TEST_CASE( "attributes" ) { } SECTION( "built-in attributes" ) { - SECTION( "bases<>" ) { +#if defined(__GNUG__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4996 ) +#endif using bases_t = decltype(get_bases(reflect())); +#if defined(__GNUG__) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning( pop ) +#endif REQUIRE( bases_t::size == 1 ); REQUIRE( std::is_same_v::type, Base> ); } diff --git a/test/060-Utils.hpp b/test/060-Utils.hpp index c0ac15a..940bc00 100644 --- a/test/060-Utils.hpp +++ b/test/060-Utils.hpp @@ -48,7 +48,7 @@ TEST_CASE( "utilities" ) { // Do nothing. }); - std::array fe{}; + std::array fe{}; util::for_each(type_list{}, [&](auto, size_t i) { fe[i] = i; }); @@ -63,7 +63,7 @@ TEST_CASE( "utilities" ) { } SECTION( "count_if" ) { - constexpr int cnt = util::count_if(type_list{}, [](auto x) { + constexpr auto cnt = util::count_if(type_list{}, [](auto x) { return std::is_integral_v; }); REQUIRE( cnt == 1 ); From 2874787d90974166cb8ffb389c5c0c24a048d461 Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 21 Mar 2022 11:00:21 -0700 Subject: [PATCH 2/4] fix release build warning --- examples/example-custom-rtti.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-custom-rtti.cpp b/examples/example-custom-rtti.cpp index 5830372..fc1bc1a 100644 --- a/examples/example-custom-rtti.cpp +++ b/examples/example-custom-rtti.cpp @@ -109,7 +109,7 @@ int main() { FirstPersonController fpc; Pawn& pawn = fpc; // refer through parent type - const TypeInfo& pawnTypeInfo = pawn.GetTypeInfo(); // get custom type info + const TypeInfo& pawnTypeInfo [[maybe_unused]] = pawn.GetTypeInfo(); // get custom type info // access the name through our TypeInfo object assert(pawnTypeInfo.Name() == "FirstPersonController"); From 518133280e0114a308178180545ec4cc921ec3a8 Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 21 Mar 2022 12:42:27 -0700 Subject: [PATCH 3/4] handle diagnostic bugs in old compiler versions --- CMakeLists.txt | 9 ++++++++- examples/example-dao.cpp | 2 +- examples/example-struct-of-arrays.cpp | 7 +++++++ include/refl.hpp | 6 +++++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9825525..9939879 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,14 @@ target_compile_features(refl-cpp INTERFACE cxx_std_17) if (MSVC) add_compile_options(/W4 /WX) else() - add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Wconversion -Werror) + add_compile_options(-Wall -Wextra -pedantic -Wconversion) + if ( NOT ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "8.0" ) ) + add_compile_options(-pedantic-errors -Werror) + endif() + if ( NOT ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "7.0" ) ) + # old versions of clang do not recognize invalid missing braces with templated code + add_compile_options(-Wno-missing-braces) + endif() endif() # ---- Install ---- diff --git a/examples/example-dao.cpp b/examples/example-dao.cpp index f7fcc53..4ea6328 100644 --- a/examples/example-dao.cpp +++ b/examples/example-dao.cpp @@ -52,7 +52,7 @@ REFL_AUTO( type(User, Table{"Users"}), field(id, Column{"ID", DataType::ID}), field(email, Column{"Email", DataType::TEXT}) -); +) template constexpr auto make_sql_field_spec(Member) diff --git a/examples/example-struct-of-arrays.cpp b/examples/example-struct-of-arrays.cpp index 1b41122..abe5fdb 100644 --- a/examples/example-struct-of-arrays.cpp +++ b/examples/example-struct-of-arrays.cpp @@ -95,6 +95,10 @@ const auto& get(const struct_of_arrays& soa) return soa[member{}]; } +#if defined(__clang__) || (defined(__GNUG__) && __GNUC__ >= 10) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmismatched-tags" +#endif namespace std { template @@ -110,6 +114,9 @@ namespace std using type = decltype(std::declval>()[descriptor{}]); }; } +#if defined(__clang__) || (defined(__GNUG__) && __GNUC__ >= 10) +#pragma GCC diagnostic pop +#endif /********************************/ diff --git a/include/refl.hpp b/include/refl.hpp index d05ab3b..95b5871 100644 --- a/include/refl.hpp +++ b/include/refl.hpp @@ -59,7 +59,11 @@ namespace std #endif // Disable warnings about non-conformant variadic macros -// There isn't any fix before c++20 +// There isn't any real standards compliant fix before c++20 + +// Note that gcc doesn't have a way to disable these warnings specifically, +// but they don't triggered for gnu variants of the standards (which CMake uses +// by default) with recent versions of the compiler. #if defined(__clang__) #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" #elif defined(_MSC_VER) From dd492d7262506bbe6ba34ea1f185ab640ca06302 Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 21 Mar 2022 13:13:02 -0700 Subject: [PATCH 4/4] workaround old clang diagnostic bugs --- CMakeLists.txt | 4 +-- include/refl.hpp | 78 ++++++++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9939879..d888ad1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,10 +28,10 @@ if (MSVC) add_compile_options(/W4 /WX) else() add_compile_options(-Wall -Wextra -pedantic -Wconversion) - if ( NOT ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "8.0" ) ) + if ( NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "8.0") ) add_compile_options(-pedantic-errors -Werror) endif() - if ( NOT ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "7.0" ) ) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "6.0") # old versions of clang do not recognize invalid missing braces with templated code add_compile_options(-Wno-missing-braces) endif() diff --git a/include/refl.hpp b/include/refl.hpp index 95b5871..0a93eec 100644 --- a/include/refl.hpp +++ b/include/refl.hpp @@ -2627,10 +2627,10 @@ namespace refl * \endcode */ template - constexpr auto get_name(Descriptor d) noexcept + constexpr auto const& get_name(Descriptor) noexcept { static_assert(trait::is_descriptor_v); - return d.name; + return Descriptor::name; } /** @@ -2644,10 +2644,10 @@ namespace refl * \endcode */ template - constexpr const auto& get_attributes(Descriptor d) noexcept + constexpr const auto& get_attributes(Descriptor) noexcept { static_assert(trait::is_descriptor_v); - return d.attributes; + return Descriptor::attributes; } /** @@ -2661,10 +2661,10 @@ namespace refl * \endcode */ template - constexpr auto get_attribute_types(Descriptor d) noexcept + constexpr auto get_attribute_types(Descriptor) noexcept { static_assert(trait::is_descriptor_v); - return trait::as_type_list_t>{}; + return trait::as_type_list_t>{}; } /** @@ -2684,10 +2684,10 @@ namespace refl * \endcode */ template - constexpr auto get_declared_base_types(TypeDescriptor t) noexcept + constexpr auto const& get_declared_base_types(TypeDescriptor) noexcept { static_assert(trait::is_type_v); - return t.declared_bases; + return TypeDescriptor::declared_bases; } /** @@ -2707,10 +2707,10 @@ namespace refl * \endcode */ template - constexpr auto get_base_types(TypeDescriptor t) noexcept + constexpr auto const& get_base_types(TypeDescriptor) noexcept { static_assert(trait::is_type_v); - return t.bases; + return TypeDescriptor::bases; } /** @@ -2728,10 +2728,10 @@ namespace refl * \endcode */ template - constexpr auto get_declared_members(TypeDescriptor t) noexcept + constexpr auto const& get_declared_members(TypeDescriptor) noexcept { static_assert(trait::is_type_v); - return t.declared_members; + return TypeDescriptor::declared_members; } /** @@ -2749,10 +2749,10 @@ namespace refl * \endcode */ template - constexpr auto get_members(TypeDescriptor t) noexcept + constexpr auto const& get_members(TypeDescriptor) noexcept { static_assert(trait::is_type_v); - return t.members; + return TypeDescriptor::members; } /** @@ -2767,10 +2767,10 @@ namespace refl * \endcode */ template - constexpr auto get_declarator(MemberDescriptor d) noexcept + constexpr auto const& get_declarator(MemberDescriptor) noexcept { static_assert(trait::is_member_v); - return d.declarator; + return MemberDescriptor::declarator; } /** @@ -2792,10 +2792,10 @@ namespace refl * \endcode */ template - constexpr auto get_pointer(MemberDescriptor d) noexcept + constexpr auto const& get_pointer(MemberDescriptor) noexcept { static_assert(trait::is_member_v); - return d.pointer; + return MemberDescriptor::pointer; } /** @@ -2835,10 +2835,10 @@ namespace refl * \endcode */ template - constexpr auto is_static(FieldDescriptor d) noexcept + constexpr auto const& is_static(FieldDescriptor) noexcept { static_assert(trait::is_field_v); - return d.is_static; + return FieldDescriptor::is_static; } /** @@ -2855,10 +2855,10 @@ namespace refl * \endcode */ template - constexpr auto is_const(FieldDescriptor d) noexcept + constexpr auto is_const(FieldDescriptor) noexcept { static_assert(trait::is_field_v); - return d.is_const; + return FieldDescriptor::is_const; } /** @@ -2883,10 +2883,10 @@ namespace refl * \endcode */ template - constexpr auto is_resolved(FunctionDescriptor d) noexcept + constexpr auto const& is_resolved(FunctionDescriptor) noexcept { static_assert(trait::is_function_v); - return d.is_resolved; + return FunctionDescriptor::is_resolved; } /** @@ -2905,10 +2905,10 @@ namespace refl * \endcode */ template - constexpr auto can_resolve(FunctionDescriptor d) noexcept + constexpr auto can_resolve(FunctionDescriptor) noexcept { static_assert(trait::is_function_v); - return d.template can_resolve(); + return FunctionDescriptor::template can_resolve(); } /** @@ -2926,10 +2926,10 @@ namespace refl * \endcode */ template - constexpr auto resolve(FunctionDescriptor d) noexcept + constexpr auto resolve(FunctionDescriptor) noexcept { static_assert(trait::is_function_v); - return d.template resolve(); + return FunctionDescriptor::template resolve(); } /** @@ -3024,10 +3024,10 @@ namespace refl * \endcode */ template - constexpr const A& get_attribute(Descriptor d) noexcept + constexpr const A& get_attribute(Descriptor) noexcept { static_assert(trait::is_descriptor_v); - return util::get(d.attributes); + return util::get(Descriptor::attributes); } /** @@ -3039,10 +3039,10 @@ namespace refl * \endcode */ template typename A, typename Descriptor> - constexpr const auto& get_attribute(Descriptor d) noexcept + constexpr const auto& get_attribute(Descriptor) noexcept { static_assert(trait::is_descriptor_v); - return util::get_instance(d.attributes); + return util::get_instance(Descriptor::attributes); } /** @@ -3208,16 +3208,16 @@ namespace refl * \endcode */ template - constexpr auto get_simple_name(TypeDescriptor t) + constexpr auto get_simple_name(TypeDescriptor) { static_assert(trait::is_type_v); - constexpr size_t template_start = t.name.find('<'); - constexpr size_t scope_last = t.name.rfind(':', template_start); + constexpr size_t template_start = TypeDescriptor::name.find('<'); + constexpr size_t scope_last = TypeDescriptor::name.rfind(':', template_start); if constexpr (scope_last == const_string<0>::npos) { - return t.name; + return TypeDescriptor::name; } else { - return t.name.template substr(); + return TypeDescriptor::name.template substr(); } } @@ -3230,10 +3230,10 @@ namespace refl * \endcode */ template - constexpr auto get_debug_name_const(MemberDescriptor d) + constexpr auto get_debug_name_const(MemberDescriptor) { static_assert(trait::is_member_v); - return d.declarator.name + "::" + d.name; + return MemberDescriptor::declarator.name + "::" + MemberDescriptor::name; } /**