Skip to content

Commit d9a5007

Browse files
nlohmannslowriot
authored andcommitted
Fix weak-vtables warning (nlohmann#4500)
* 🔧 remove warning suppression * 🚨 fix weak-vtables warning nlohmann#4087 * 🚨 suppress -Wweak-vtables warning * 🚨 suppress -Wweak-vtables warning * ✅ fix test * ✅ fix test * ✅ fix test
1 parent d48d16e commit d9a5007

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

cmake/ci.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
9696
# -Wno-padded We do not care about padding warnings.
9797
# -Wno-covered-switch-default All switches list all cases and a default case.
9898
# -Wno-unsafe-buffer-usage Otherwise Doctest would not compile.
99-
# -Wno-weak-vtables The library is header-only.
10099
# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536.
101100

102101
set(CLANG_CXXFLAGS
@@ -109,7 +108,6 @@ set(CLANG_CXXFLAGS
109108
-Wno-padded
110109
-Wno-covered-switch-default
111110
-Wno-unsafe-buffer-usage
112-
-Wno-weak-vtables
113111
-Wno-reserved-identifier
114112
)
115113

include/nlohmann/detail/exceptions.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@
2525
#include <nlohmann/detail/meta/type_traits.hpp>
2626
#include <nlohmann/detail/string_concat.hpp>
2727

28+
// With -Wweak-vtables, Clang will complain about the exception classes as they
29+
// have no out-of-line virtual method definitions and their vtable will be
30+
// emitted in every translation unit. This issue cannot be fixed with a
31+
// header-only library as there is no implementation file to move these
32+
// functions to. As a result, we suppress this warning here to avoid client
33+
// code to stumble over this. See https://github.com/nlohmann/json/issues/4087
34+
// for a discussion.
35+
#if defined(__clang__)
36+
#pragma clang diagnostic push
37+
#pragma clang diagnostic ignored "-Wweak-vtables"
38+
#endif
39+
2840
NLOHMANN_JSON_NAMESPACE_BEGIN
2941
namespace detail
3042
{
@@ -255,3 +267,7 @@ class other_error : public exception
255267

256268
} // namespace detail
257269
NLOHMANN_JSON_NAMESPACE_END
270+
271+
#if defined(__clang__)
272+
#pragma clang diagnostic pop
273+
#endif

single_include/nlohmann/json.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4392,6 +4392,18 @@ inline OutStringType concat(Args && ... args)
43924392
NLOHMANN_JSON_NAMESPACE_END
43934393

43944394

4395+
// With -Wweak-vtables, Clang will complain about the exception classes as they
4396+
// have no out-of-line virtual method definitions and their vtable will be
4397+
// emitted in every translation unit. This issue cannot be fixed with a
4398+
// header-only library as there is no implementation file to move these
4399+
// functions to. As a result, we suppress this warning here to avoid client
4400+
// code to stumble over this. See https://github.com/nlohmann/json/issues/4087
4401+
// for a discussion.
4402+
#if defined(__clang__)
4403+
#pragma clang diagnostic push
4404+
#pragma clang diagnostic ignored "-Wweak-vtables"
4405+
#endif
4406+
43954407
NLOHMANN_JSON_NAMESPACE_BEGIN
43964408
namespace detail
43974409
{
@@ -4623,6 +4635,10 @@ class other_error : public exception
46234635
} // namespace detail
46244636
NLOHMANN_JSON_NAMESPACE_END
46254637

4638+
#if defined(__clang__)
4639+
#pragma clang diagnostic pop
4640+
#endif
4641+
46264642
// #include <nlohmann/detail/macro_scope.hpp>
46274643

46284644
// #include <nlohmann/detail/meta/cpp_future.hpp>

tests/src/unit-regression2.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,33 @@ inline void from_json(const nlohmann::json& j, FooBar& fb) // NOLINT(misc-use-in
233233
struct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
234234
{
235235
for_3171_base(const std::string& /*unused*/ = {}) {}
236-
virtual ~for_3171_base() = default;
236+
virtual ~for_3171_base();
237+
238+
for_3171_base(const for_3171_base& other) // NOLINT(hicpp-use-equals-default,modernize-use-equals-default)
239+
: str(other.str)
240+
{}
241+
242+
for_3171_base& operator=(const for_3171_base& other)
243+
{
244+
if (this != &other)
245+
{
246+
str = other.str;
247+
}
248+
return *this;
249+
}
250+
251+
for_3171_base(for_3171_base&& other) noexcept
252+
: str(std::move(other.str))
253+
{}
254+
255+
for_3171_base& operator=(for_3171_base&& other) noexcept
256+
{
257+
if (this != &other)
258+
{
259+
str = std::move(other.str);
260+
}
261+
return *this;
262+
}
237263

238264
virtual void _from_json(const json& j)
239265
{
@@ -243,12 +269,43 @@ struct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
243269
std::string str{}; // NOLINT(readability-redundant-member-init)
244270
};
245271

272+
for_3171_base::~for_3171_base() = default;
273+
246274
struct for_3171_derived : public for_3171_base
247275
{
248276
for_3171_derived() = default;
277+
~for_3171_derived() override;
249278
explicit for_3171_derived(const std::string& /*unused*/) { }
279+
280+
for_3171_derived(const for_3171_derived& other) // NOLINT(hicpp-use-equals-default,modernize-use-equals-default)
281+
: for_3171_base(other)
282+
{}
283+
284+
for_3171_derived& operator=(const for_3171_derived& other)
285+
{
286+
if (this != &other)
287+
{
288+
for_3171_base::operator=(other); // Call base class assignment operator
289+
}
290+
return *this;
291+
}
292+
293+
for_3171_derived(for_3171_derived&& other) noexcept
294+
: for_3171_base(std::move(other))
295+
{}
296+
297+
for_3171_derived& operator=(for_3171_derived&& other) noexcept
298+
{
299+
if (this != &other)
300+
{
301+
for_3171_base::operator=(std::move(other)); // Call base class move assignment operator
302+
}
303+
return *this;
304+
}
250305
};
251306

307+
for_3171_derived::~for_3171_derived() = default;
308+
252309
inline void from_json(const json& j, for_3171_base& tb) // NOLINT(misc-use-internal-linkage)
253310
{
254311
tb._from_json(j);

0 commit comments

Comments
 (0)