From 2d1a84cae8cc03ce804a4d18c29e37748baec4f4 Mon Sep 17 00:00:00 2001 From: "Otto C." <12378062+ILer32@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:57:35 +0800 Subject: [PATCH 1/2] correct functions to prevent dangling string --- include/boost/ut.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/boost/ut.hpp b/include/boost/ut.hpp index 5c020635..14aa8f16 100644 --- a/include/boost/ut.hpp +++ b/include/boost/ut.hpp @@ -3078,11 +3078,11 @@ struct suite { [[maybe_unused]] inline auto log = detail::log{}; [[maybe_unused]] inline auto that = detail::that_{}; -[[maybe_unused]] constexpr auto test = [](const auto name) { +[[maybe_unused]] constexpr auto test = [](const auto& name) { return detail::test{"test", name}; }; [[maybe_unused]] constexpr auto should = test; -[[maybe_unused]] inline auto tag = [](const auto name) { +[[maybe_unused]] inline auto tag = [](const auto& name) { return detail::tag{{name}}; }; [[maybe_unused]] inline auto skip = tag("skip"); @@ -3139,19 +3139,19 @@ template } namespace bdd { -[[maybe_unused]] constexpr auto feature = [](const auto name) { +[[maybe_unused]] constexpr auto feature = [](const auto& name) { return detail::test{"feature", name}; }; -[[maybe_unused]] constexpr auto scenario = [](const auto name) { +[[maybe_unused]] constexpr auto scenario = [](const auto& name) { return detail::test{"scenario", name}; }; -[[maybe_unused]] constexpr auto given = [](const auto name) { +[[maybe_unused]] constexpr auto given = [](const auto& name) { return detail::test{"given", name}; }; -[[maybe_unused]] constexpr auto when = [](const auto name) { +[[maybe_unused]] constexpr auto when = [](const auto& name) { return detail::test{"when", name}; }; -[[maybe_unused]] constexpr auto then = [](const auto name) { +[[maybe_unused]] constexpr auto then = [](const auto& name) { return detail::test{"then", name}; }; @@ -3283,10 +3283,10 @@ class steps { } // namespace bdd namespace spec { -[[maybe_unused]] constexpr auto describe = [](const auto name) { +[[maybe_unused]] constexpr auto describe = [](const auto& name) { return detail::test{"describe", name}; }; -[[maybe_unused]] constexpr auto it = [](const auto name) { +[[maybe_unused]] constexpr auto it = [](const auto& name) { return detail::test{"it", name}; }; } // namespace spec From d68a4617e5dc2a23b1769a1d2332b31291cde040 Mon Sep 17 00:00:00 2001 From: "Otto C." <12378062+ILer32@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:38:48 +0800 Subject: [PATCH 2/2] improve struct test to prevent dangling string --- include/boost/ut.hpp | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/include/boost/ut.hpp b/include/boost/ut.hpp index 14aa8f16..8869d9fb 100644 --- a/include/boost/ut.hpp +++ b/include/boost/ut.hpp @@ -2240,9 +2240,17 @@ struct test_location { struct test { std::string_view type{}; + std::optional backingName; std::string_view name{}; std::vector tag{}; + test(std::string_view t, std::string_view sv) : type(t), name(sv) {} + test(std::string_view t, const std::string& s) : type(t), name(s) {} + test(std::string_view t, const char* s) : type(t), name(s) {} + template + test(std::string_view t, const char (&s)[N]) : type(t), name(s) {} + test(std::string_view t, std::string&& s) : type(t), backingName(std::move(s)), name(*backingName) {} + template constexpr auto operator=(test_location _test) { on(events::test{.type = type, @@ -3078,8 +3086,8 @@ struct suite { [[maybe_unused]] inline auto log = detail::log{}; [[maybe_unused]] inline auto that = detail::that_{}; -[[maybe_unused]] constexpr auto test = [](const auto& name) { - return detail::test{"test", name}; +[[maybe_unused]] constexpr auto test = [](auto&& name) { + return detail::test{"test", std::forward(name)}; }; [[maybe_unused]] constexpr auto should = test; [[maybe_unused]] inline auto tag = [](const auto& name) { @@ -3139,20 +3147,20 @@ template } namespace bdd { -[[maybe_unused]] constexpr auto feature = [](const auto& name) { - return detail::test{"feature", name}; +[[maybe_unused]] constexpr auto feature = [](auto&& name) { + return detail::test{"feature", std::forward(name)}; }; -[[maybe_unused]] constexpr auto scenario = [](const auto& name) { - return detail::test{"scenario", name}; +[[maybe_unused]] constexpr auto scenario = [](auto&& name) { + return detail::test{"scenario", std::forward(name)}; }; -[[maybe_unused]] constexpr auto given = [](const auto& name) { - return detail::test{"given", name}; +[[maybe_unused]] constexpr auto given = [](auto&& name) { + return detail::test{"given", std::forward(name)}; }; -[[maybe_unused]] constexpr auto when = [](const auto& name) { - return detail::test{"when", name}; +[[maybe_unused]] constexpr auto when = [](auto&& name) { + return detail::test{"when", std::forward(name)}; }; -[[maybe_unused]] constexpr auto then = [](const auto& name) { - return detail::test{"then", name}; +[[maybe_unused]] constexpr auto then = [](auto&& name) { + return detail::test{"then", std::forward(name)}; }; namespace gherkin { @@ -3283,11 +3291,11 @@ class steps { } // namespace bdd namespace spec { -[[maybe_unused]] constexpr auto describe = [](const auto& name) { - return detail::test{"describe", name}; +[[maybe_unused]] constexpr auto describe = [](auto&& name) { + return detail::test{"describe", std::forward(name)}; }; -[[maybe_unused]] constexpr auto it = [](const auto& name) { - return detail::test{"it", name}; +[[maybe_unused]] constexpr auto it = [](auto&& name) { + return detail::test{"it", std::forward(name)}; }; } // namespace spec