mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 15:34:50 +07:00
* Re-amalgamate single_include after #5737 #5737 changed sources under include/ without regenerating single_include, so the single header on develop is out of date. This commit only runs make amalgamate. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Suppress GCC's false -Warray-bounds error in set_parents() with JSON_DIAGNOSTICS With JSON_DIAGNOSTICS, GCC 13 to 15 report a false -Warray-bounds error at -O3 when set_parents() is inlined right after a non-container value (e.g., a string) was created: the std::map access in the object branch is checked against the string allocation although m_type rules that branch out. GCC 15 fixed the pattern from #4819 but not this one. Suppress -Warray-bounds around set_parents() only, and add a regression test that is compiled with -O3 -Werror=array-bounds on GCC. Fixes #5742 Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the false -Warray-bounds error by setting the type after the value The pragma around set_parents() is no longer needed: the base branch (#5585) creates a value before setting its type. Before, the type of a new string was stored first, so GCC had to assume that operator new could change it again, kept the object branch of the inlined set_parents() alive, and checked it against the string's allocation. Rewriting set_parents() itself (if/else instead of switch) does not help. Verified with Docker GCC 12.5, 13, 14, 15.3 and 16.2: the regression test builds and passes without the pragma, and fails to build on develop. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
81 lines
2.5 KiB
C++
81 lines
2.5 KiB
C++
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Regression test for https://github.com/nlohmann/json/issues/5742: with
|
|
// JSON_DIAGNOSTICS, GCC (12 to at least 16) reported a false -Warray-bounds
|
|
// error in the inlined set_parents() at -O3. The type of a new string was set
|
|
// before the string was allocated, so GCC had to assume that operator new
|
|
// could change it again and checked the object branch of set_parents()
|
|
// against the string's allocation. Setting the type after creating the value
|
|
// avoids this. The warning depends on GCC's inlining decisions, so the
|
|
// sections cover two patterns that trigger it on different GCC versions
|
|
// (#4819 and #5742).
|
|
// On GCC, this file is compiled with -O3 -Werror=array-bounds (see
|
|
// tests/CMakeLists.txt), so the test fails to build if the warning returns.
|
|
|
|
#include "doctest_compatibility.h"
|
|
|
|
#ifdef JSON_DIAGNOSTICS
|
|
#undef JSON_DIAGNOSTICS
|
|
#endif
|
|
|
|
#define JSON_DIAGNOSTICS 1
|
|
|
|
#include <nlohmann/json.hpp>
|
|
using nlohmann::json;
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
enum class diag_color
|
|
{
|
|
red,
|
|
green,
|
|
blue
|
|
};
|
|
|
|
void to_json(json& j, const diag_color& c)
|
|
{
|
|
static const std::pair<diag_color, json> m[] = // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
|
{
|
|
{diag_color::red, "r"},
|
|
{diag_color::green, "g"},
|
|
{diag_color::blue, "b"},
|
|
};
|
|
const auto* it = std::find_if(std::begin(m), std::end(m), [c](const std::pair<diag_color, json>& p)
|
|
{
|
|
return p.first == c;
|
|
});
|
|
j = it->second;
|
|
}
|
|
} // namespace
|
|
|
|
TEST_CASE("diagnostics with optimization")
|
|
{
|
|
SECTION("issue #4819 - object in vector")
|
|
{
|
|
std::vector<json> jsons{};
|
|
jsons.emplace_back(json({{"key", "value"}}));
|
|
CHECK(jsons.back()["key"] == "value");
|
|
}
|
|
|
|
SECTION("issue #5742 - string values from a static table")
|
|
{
|
|
json j = json::array();
|
|
j.push_back(diag_color::red);
|
|
j.push_back(diag_color::green);
|
|
j.push_back(diag_color::blue);
|
|
CHECK(j.dump() == R"(["r","g","b"])");
|
|
CHECK_THROWS_WITH_AS(j[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
|
|
}
|
|
}
|