Skip to content

Commit 6d6ccbc

Browse files
committed
fix: avoid per-instantiation vtable issues with MinGW GCC in doctest
Replace INFO() macro calls with concrete StringContextScope class to work around MinGW GCC generating a unique vtable per template instantiation. INFO() creates ContextScope<Lambda> which triggers this issue; the concrete class has a single vtable definition shared across all instantiations. - Add StringContextScope struct inheriting from doctest::detail::ContextScopeBase - Add make_context_info() helper to create context without template lambdas - Update CHECK_BATCH_EQ, CHECK_SCALAR_EQ, CHECK_VECTOR_EQ macros to use new helper
1 parent f9079f1 commit 6d6ccbc

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

test/test_utils.hpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -386,27 +386,46 @@ namespace detail
386386
b.store_unaligned(dst.data() + i);
387387
}
388388

389+
// Non-template context scope to avoid per-instantiation vtable issues with MinGW GCC.
390+
// INFO() creates a ContextScope<Lambda> with a unique vtable per template instantiation.
391+
// This concrete class has a single vtable definition shared across all instantiations.
392+
struct StringContextScope : doctest::detail::ContextScopeBase
393+
{
394+
std::string msg_;
395+
explicit StringContextScope(std::string msg)
396+
: msg_(std::move(msg))
397+
{
398+
}
399+
void stringify(std::ostream* os) const override { *os << msg_; }
400+
};
401+
402+
template <class T>
403+
StringContextScope make_context_info(const char* name, const T& val)
404+
{
405+
return StringContextScope(std::string(name) + ":" + doctest::toString(val).c_str());
406+
}
407+
389408
}
390409

391-
#define CHECK_BATCH_EQ(b1, b2) \
392-
do \
393-
{ \
394-
INFO(#b1 ":", b1); \
395-
INFO(#b2 ":", b2); \
396-
CHECK_UNARY(::detail::expect_batch_near(b1, b2)); \
410+
#define CHECK_BATCH_EQ(b1, b2) \
411+
do \
412+
{ \
413+
auto _ctx1 = ::detail::make_context_info(#b1, b1); \
414+
auto _ctx2 = ::detail::make_context_info(#b2, b2); \
415+
CHECK_UNARY(::detail::expect_batch_near(b1, b2)); \
397416
} while (0)
398417
#define CHECK_SCALAR_EQ(s1, s2) \
399418
do \
400419
{ \
401-
INFO(#s1 ":", s1); \
402-
INFO(#s2 ":", s2); \
420+
auto _ctx1 = ::detail::make_context_info(#s1, s1); \
421+
auto _ctx2 = ::detail::make_context_info(#s2, s2); \
403422
CHECK_UNARY(::detail::expect_scalar_near(s1, s2)); \
404423
} while (0)
405424
#define CHECK_VECTOR_EQ(v1, v2) \
406425
do \
407426
{ \
408-
INFO(#v1 ":", v1); \
409-
INFO(#v2 ":", v2); \
427+
auto _ctx1 = ::detail::make_context_info(#v1, v1); \
428+
auto _ctx2 = ::detail::make_context_info(#v2, v2); \
410429
CHECK_UNARY(::detail::expect_vector_near(v1, v2)); \
411430
} while (0)
412431

0 commit comments

Comments
 (0)