Fix C++20/gcc-12 issues (Part 1) (#3379)
* 🔧 use proper GCC binary * 🔧 add more GCC warning flags * ⚗️ try fix from https://github.com/nlohmann/json/issues/3138#issuecomment-1015562666 * Fix custom allocator test build failures (C++20) Allocator tests fail to compile in C++20 mode with clang+MS STL due to missing copy constructors. * Fix test build failures due to missing noexcept (gcc-12) * alt_string has multiple member functions that should be marked noexcept. * nlohmann::ordered_map constructors can be noexcept. Compilation failures result from the warning flag -Werror=noexcept and gcc-12. * Disable broken comparison tests in C++20 mode Co-authored-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
parent
4a6e6ca8c7
commit
f208a9c19b
@ -30,7 +30,7 @@ execute_process(COMMAND ${CPPCHECK_TOOL} --version OUTPUT_VARIABLE CPPCHECK_TOOL
|
||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CPPCHECK_TOOL_VERSION "${CPPCHECK_TOOL_VERSION}")
|
||||
message(STATUS "🔖 Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})")
|
||||
|
||||
find_program(GCC_TOOL NAMES g++-HEAD g++-11 g++-latest)
|
||||
find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++-11)
|
||||
execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)
|
||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
||||
message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})")
|
||||
@ -111,6 +111,7 @@ set(CLANG_CXXFLAGS "-std=c++11 \
|
||||
-Wno-reserved-identifier \
|
||||
")
|
||||
|
||||
# Warning flags determined for GCC 12.0 (experimental) with https://github.com/nlohmann/gcc_flags:
|
||||
# Ignored GCC warnings:
|
||||
# -Wno-abi-tag We do not care about ABI tags.
|
||||
# -Wno-aggregate-return The library uses aggregate returns.
|
||||
@ -150,16 +151,22 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wanalyzer-shift-count-negative \
|
||||
-Wanalyzer-shift-count-overflow \
|
||||
-Wanalyzer-stale-setjmp-buffer \
|
||||
-Wanalyzer-tainted-allocation-size \
|
||||
-Wanalyzer-tainted-array-index \
|
||||
-Wanalyzer-tainted-divisor \
|
||||
-Wanalyzer-tainted-offset \
|
||||
-Wanalyzer-tainted-size \
|
||||
-Wanalyzer-too-complex \
|
||||
-Wanalyzer-unsafe-call-within-signal-handler \
|
||||
-Wanalyzer-use-after-free \
|
||||
-Wanalyzer-use-of-pointer-in-stale-stack-frame \
|
||||
-Wanalyzer-use-of-uninitialized-value \
|
||||
-Wanalyzer-write-to-const \
|
||||
-Wanalyzer-write-to-string-literal \
|
||||
-Warith-conversion \
|
||||
-Warray-bounds \
|
||||
-Warray-bounds=2 \
|
||||
-Warray-compare \
|
||||
-Warray-parameter=2 \
|
||||
-Wattribute-alias=2 \
|
||||
-Wattribute-warning \
|
||||
@ -170,10 +177,15 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wbuiltin-macro-redefined \
|
||||
-Wc++0x-compat \
|
||||
-Wc++11-compat \
|
||||
-Wc++11-extensions \
|
||||
-Wc++14-compat \
|
||||
-Wc++14-extensions \
|
||||
-Wc++17-compat \
|
||||
-Wc++17-extensions \
|
||||
-Wc++1z-compat \
|
||||
-Wc++20-compat \
|
||||
-Wc++20-extensions \
|
||||
-Wc++23-extensions \
|
||||
-Wc++2a-compat \
|
||||
-Wcannot-profile \
|
||||
-Wcast-align \
|
||||
@ -191,6 +203,7 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wconditionally-supported \
|
||||
-Wconversion \
|
||||
-Wconversion-null \
|
||||
-Wcoverage-invalid-line-number \
|
||||
-Wcoverage-mismatch \
|
||||
-Wcpp \
|
||||
-Wctad-maybe-unsupported \
|
||||
@ -215,21 +228,16 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wendif-labels \
|
||||
-Wenum-compare \
|
||||
-Wenum-conversion \
|
||||
-Wexceptions \
|
||||
-Wexpansion-to-defined \
|
||||
-Wextra \
|
||||
-Wextra-semi \
|
||||
-Wfloat-conversion \
|
||||
-Wfloat-equal \
|
||||
-Wformat-contains-nul \
|
||||
-Wformat-diag \
|
||||
-Wformat-extra-args \
|
||||
-Wformat-nonliteral \
|
||||
-Wformat-overflow=2 \
|
||||
-Wformat-security \
|
||||
-Wformat-signedness \
|
||||
-Wformat-truncation=2 \
|
||||
-Wformat-y2k \
|
||||
-Wformat-zero-length \
|
||||
-Wformat=2 \
|
||||
-Wframe-address \
|
||||
-Wfree-nonheap-object \
|
||||
@ -239,12 +247,15 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wignored-qualifiers \
|
||||
-Wimplicit-fallthrough=5 \
|
||||
-Winaccessible-base \
|
||||
-Winfinite-recursion \
|
||||
-Winherited-variadic-ctor \
|
||||
-Winit-list-lifetime \
|
||||
-Winit-self \
|
||||
-Winline \
|
||||
-Wint-in-bool-context \
|
||||
-Wint-to-pointer-cast \
|
||||
-Winterference-size \
|
||||
-Winvalid-imported-macros \
|
||||
-Winvalid-memory-model \
|
||||
-Winvalid-offsetof \
|
||||
-Winvalid-pch \
|
||||
@ -267,6 +278,7 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wmissing-field-initializers \
|
||||
-Wmissing-include-dirs \
|
||||
-Wmissing-profile \
|
||||
-Wmissing-requires \
|
||||
-Wmultichar \
|
||||
-Wmultiple-inheritance \
|
||||
-Wmultistatement-macros \
|
||||
@ -282,6 +294,7 @@ set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-Wnull-dereference \
|
||||
-Wodr \
|
||||
-Wold-style-cast \
|
||||
-Wopenacc-parallelism \
|
||||
-Wopenmp-simd \
|
||||
-Woverflow \
|
||||
-Woverlength-strings \
|
||||
|
@ -1872,6 +1872,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
template < typename ValueType, typename std::enable_if <
|
||||
detail::conjunction <
|
||||
detail::negation<std::is_pointer<ValueType>>,
|
||||
detail::negation<std::is_same<ValueType, std::nullptr_t>>,
|
||||
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
||||
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
||||
detail::negation<detail::is_basic_json<ValueType>>,
|
||||
|
@ -30,7 +30,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||
|
||||
// Explicit constructors instead of `using Container::Container`
|
||||
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
||||
ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
|
||||
ordered_map() noexcept(noexcept(Container())) : Container{} {}
|
||||
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
|
||||
template <class It>
|
||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||
: Container{first, last, alloc} {}
|
||||
|
@ -17066,7 +17066,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||
|
||||
// Explicit constructors instead of `using Container::Container`
|
||||
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
||||
ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
|
||||
ordered_map() noexcept(noexcept(Container())) : Container{} {}
|
||||
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
|
||||
template <class It>
|
||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||
: Container{first, last, alloc} {}
|
||||
@ -19052,6 +19053,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
template < typename ValueType, typename std::enable_if <
|
||||
detail::conjunction <
|
||||
detail::negation<std::is_pointer<ValueType>>,
|
||||
detail::negation<std::is_same<ValueType, std::nullptr_t>>,
|
||||
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
||||
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
||||
detail::negation<detail::is_basic_json<ValueType>>,
|
||||
|
@ -39,6 +39,8 @@ namespace
|
||||
template<class T>
|
||||
struct bad_allocator : std::allocator<T>
|
||||
{
|
||||
using std::allocator<T>::allocator;
|
||||
|
||||
template<class... Args>
|
||||
void construct(T* /*unused*/, Args&& ... /*unused*/)
|
||||
{
|
||||
|
@ -104,12 +104,12 @@ class alt_string
|
||||
}
|
||||
|
||||
template <typename op_type>
|
||||
bool operator<(const op_type& op) const
|
||||
bool operator<(const op_type& op) const noexcept
|
||||
{
|
||||
return str_impl < op;
|
||||
}
|
||||
|
||||
bool operator<(const alt_string& op) const
|
||||
bool operator<(const alt_string& op) const noexcept
|
||||
{
|
||||
return str_impl < op.str_impl;
|
||||
}
|
||||
|
@ -32,6 +32,10 @@ SOFTWARE.
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||
#define JSON_HAS_CPP_20
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
// helper function to check std::less<json::value_t>
|
||||
@ -205,6 +209,14 @@ TEST_CASE("lexicographical comparison operators")
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
// Skip comparing indicies 12 and 13, and 13 and 12 in C++20 pending fix
|
||||
// See issue #3207
|
||||
#ifdef JSON_HAS_CPP_20
|
||||
if ((i == 12 && j == 13) || (i == 13 && j == 12))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
CAPTURE(j_values[i])
|
||||
|
@ -271,7 +271,10 @@ std::string* sax_no_exception::error_string = nullptr;
|
||||
|
||||
template<class T>
|
||||
class my_allocator : public std::allocator<T>
|
||||
{};
|
||||
{
|
||||
public:
|
||||
using std::allocator<T>::allocator;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #3077
|
||||
@ -338,7 +341,7 @@ TEST_CASE("regression tests 2")
|
||||
]
|
||||
})";
|
||||
|
||||
json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed)
|
||||
json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed) noexcept
|
||||
{
|
||||
// skip uninteresting events
|
||||
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
||||
|
Loading…
Reference in New Issue
Block a user