mirror of
https://github.com/boostorg/variant2.git
synced 2026-01-13 18:56:59 +01:00
Compare commits
10 Commits
feature/gh
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
155ed414ab | ||
|
|
e6b336ec68 | ||
|
|
799a69eccc | ||
|
|
74f6f0cd96 | ||
|
|
fc786d39b3 | ||
|
|
382cf33824 | ||
|
|
4632862a4b | ||
|
|
48ed0a243f | ||
|
|
936a1a95b5 | ||
|
|
fcdaadb0f5 |
@@ -34,7 +34,6 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
|
||||
'set -e',
|
||||
'uname -a',
|
||||
'echo $DRONE_STAGE_MACHINE',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
@@ -213,6 +212,13 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 25.04 GCC 15 32/64",
|
||||
"cppalliance/droneubuntu2504:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '11,14,17,20,23,2c', ADDRMD: '32,64' },
|
||||
"g++-15-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.5",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
@@ -340,40 +346,47 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 17 UBSAN",
|
||||
"Linux 24.04 Clang 17",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 17 ASAN",
|
||||
"Linux 24.04 Clang 18",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 ASAN",
|
||||
"Linux 24.04 Clang 19",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.10 Clang 19",
|
||||
"cppalliance/droneubuntu2410:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-19",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 20 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + ubsan,
|
||||
"clang-20",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 20 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + asan,
|
||||
"clang-20",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 25.10 Clang 21",
|
||||
"cppalliance/droneubuntu2510:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-21', CXXSTD: '11,14,17,20,23,2c' },
|
||||
"clang-21",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,
|
||||
@@ -437,4 +450,16 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2026 msvc-14.5",
|
||||
"cppalliance/dronevs2026:1",
|
||||
{ TOOLSET: 'msvc-14.5', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2026 msvc-14.5 permissive-",
|
||||
"cppalliance/dronevs2026:1",
|
||||
{ TOOLSET: 'msvc-14.5', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
|
||||
),
|
||||
]
|
||||
|
||||
@@ -93,7 +93,7 @@ struct monostate
|
||||
{
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1950)
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1960)
|
||||
|
||||
constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
||||
constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
||||
@@ -558,10 +558,20 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_false, T1, T.
|
||||
T1 first_;
|
||||
variant_storage<T...> rest_;
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
// false positive, see https://github.com/boostorg/variant2/issues/55
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
@@ -704,6 +714,7 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_true, T1, T..
|
||||
# pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
*this = variant_storage_impl( mp11::mp_size_t<I>(), std::forward<A>(a)... );
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 7)
|
||||
@@ -1071,7 +1082,18 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I ) const noexcept
|
||||
{
|
||||
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
// false positive, see https://github.com/boostorg/variant2/issues/55
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
this_->st_.get( I() ).~U();
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1119,8 +1141,18 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
|
||||
static_assert( std::is_nothrow_move_constructible<U>::value, "Logic error: U must be nothrow move constructible" );
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
// false positive, see https://github.com/boostorg/variant2/issues/55
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
U tmp( std::forward<A>(a)... );
|
||||
|
||||
#if defined(BOOST_GCC) && (__GNUC__ >= 12)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
_destroy();
|
||||
|
||||
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
||||
@@ -1689,7 +1721,7 @@ public:
|
||||
class Ud = typename std::decay<U>::type,
|
||||
class E1 = typename std::enable_if< !std::is_same<Ud, variant>::value && !std::is_base_of<variant, Ud>::value && !detail::is_in_place_index<Ud>::value && !detail::is_in_place_type<Ud>::value >::type,
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1950)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1960)
|
||||
|
||||
class V = mp11::mp_apply_q< mp11::mp_bind_front<detail::resolve_overload_type, U&&>, variant >,
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
||||
|
||||
if(HAVE_BOOST_TEST)
|
||||
|
||||
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::variant2 Boost::core Boost::container_hash)
|
||||
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::variant2 Boost::core Boost::container_hash Boost::system)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -172,3 +172,12 @@ compile variant_default_construct_cx_5.cpp ;
|
||||
compile variant_value_construct_cx_2.cpp ;
|
||||
compile variant_value_construct_cx_3.cpp ;
|
||||
compile variant_value_construct_cx_4.cpp ;
|
||||
|
||||
# GCC 12+ false positive -Wmaybe-uninitialized with non-trivially-copyable types
|
||||
run variant_issue_55.cpp
|
||||
: : :
|
||||
<library>/boost/system//boost_system
|
||||
|
||||
# clang-cl 32 bit fails with an assertion in mp_with_index, likely due to a codegen bug
|
||||
"<toolset>clang-win,<address-model>32:<build>no"
|
||||
;
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because __cpp_constexpr_dynamic_alloc < 201907L")
|
||||
int main() {}
|
||||
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1950
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1960
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_MSVC < 1950")
|
||||
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_MSVC < 1960")
|
||||
int main() {}
|
||||
|
||||
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
|
||||
|
||||
194
test/variant_issue_55.cpp
Normal file
194
test/variant_issue_55.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright 2025 Peter Dimov
|
||||
// Copyright 2025 Vinnie Falco
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// GCC 12+ -Wmaybe-uninitialized false positive tests
|
||||
// https://github.com/boostorg/variant2/issues/55
|
||||
//
|
||||
// GCC 12+'s improved dataflow analysis sees code paths for all alternatives
|
||||
// in mp_with_index and warns that members may be uninitialized, even though
|
||||
// the variant's discriminator guarantees only initialized alternatives are
|
||||
// accessed.
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
// Check for C++17 std::optional support
|
||||
#if BOOST_CXX_VERSION >= 201703L
|
||||
# include <optional>
|
||||
# define BOOST_VARIANT2_TEST_HAS_OPTIONAL 1
|
||||
#endif
|
||||
|
||||
// Check for C++20 coroutine support
|
||||
#if defined(__cpp_impl_coroutine) && __cpp_impl_coroutine >= 201902L
|
||||
# include <coroutine>
|
||||
# define BOOST_VARIANT2_TEST_HAS_CORO 1
|
||||
#endif
|
||||
|
||||
using result_void = boost::system::result<void, std::exception_ptr>;
|
||||
using result_string = boost::system::result<std::string, std::exception_ptr>;
|
||||
|
||||
void testGccUninitialized()
|
||||
{
|
||||
// Test 1: Simple copy construction
|
||||
{
|
||||
result_void r1;
|
||||
result_void r2(r1);
|
||||
(void)r2;
|
||||
}
|
||||
|
||||
// Test 2: Copy assignment
|
||||
{
|
||||
result_void r1;
|
||||
result_void r2;
|
||||
r2 = r1;
|
||||
(void)r2;
|
||||
}
|
||||
|
||||
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
|
||||
// Test 3: std::optional assignment (matches spawn pattern)
|
||||
{
|
||||
std::optional<result_void> opt;
|
||||
opt = result_void{};
|
||||
(void)opt;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Test 4: Pass to function via copy
|
||||
{
|
||||
auto fn = [](result_void r) { (void)r; };
|
||||
fn(result_void{});
|
||||
}
|
||||
|
||||
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
|
||||
// Test 5: Lambda capture + optional (closest to spawn)
|
||||
{
|
||||
auto fn = [](result_void r) {
|
||||
std::optional<result_void> opt;
|
||||
opt = r;
|
||||
return opt.has_value();
|
||||
};
|
||||
(void)fn(result_void{});
|
||||
}
|
||||
#endif
|
||||
|
||||
// Test 6: Non-void result with string (triggers string warning)
|
||||
{
|
||||
result_string r1;
|
||||
result_string r2(r1);
|
||||
(void)r2;
|
||||
}
|
||||
|
||||
// Test 7: Assign exception to result holding value
|
||||
{
|
||||
result_string r1{"hello"};
|
||||
r1 = std::make_exception_ptr(std::runtime_error("test"));
|
||||
(void)r1;
|
||||
}
|
||||
|
||||
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
|
||||
// Test 8: Optional with string result
|
||||
{
|
||||
std::optional<result_string> opt;
|
||||
opt = result_string{};
|
||||
(void)opt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_VARIANT2_TEST_HAS_CORO
|
||||
// Minimal fire-and-forget coroutine for testing
|
||||
struct fire_and_forget
|
||||
{
|
||||
struct promise_type
|
||||
{
|
||||
fire_and_forget get_return_object() { return {}; }
|
||||
std::suspend_never initial_suspend() noexcept { return {}; }
|
||||
std::suspend_never final_suspend() noexcept { return {}; }
|
||||
void return_void() {}
|
||||
void unhandled_exception() { std::terminate(); }
|
||||
};
|
||||
};
|
||||
|
||||
// Test 9: Coroutine returning result (mimics spawn)
|
||||
{
|
||||
auto coro = []() -> fire_and_forget {
|
||||
result_void r{};
|
||||
(void)r;
|
||||
co_return;
|
||||
};
|
||||
coro();
|
||||
}
|
||||
|
||||
// Test 10: Coroutine with handler call (closest to actual spawn)
|
||||
{
|
||||
std::optional<result_void> received;
|
||||
auto handler = [&](result_void r) {
|
||||
received = r;
|
||||
};
|
||||
auto coro = [&]() -> fire_and_forget {
|
||||
handler(result_void{});
|
||||
co_return;
|
||||
};
|
||||
coro();
|
||||
(void)received;
|
||||
}
|
||||
|
||||
// Test 11: Coroutine with try/catch like spawn
|
||||
{
|
||||
std::optional<result_void> received;
|
||||
auto handler = [&](result_void r) {
|
||||
received = r;
|
||||
};
|
||||
auto coro = [&]() -> fire_and_forget {
|
||||
try
|
||||
{
|
||||
handler(result_void{});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
handler(result_void{std::current_exception()});
|
||||
}
|
||||
co_return;
|
||||
};
|
||||
coro();
|
||||
(void)received;
|
||||
}
|
||||
|
||||
// Test 12: Coroutine with string result
|
||||
{
|
||||
std::optional<result_string> received;
|
||||
auto handler = [&](result_string r) {
|
||||
received = r;
|
||||
};
|
||||
auto coro = [&]() -> fire_and_forget {
|
||||
try
|
||||
{
|
||||
handler(result_string{"test"});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
handler(result_string{std::current_exception()});
|
||||
}
|
||||
co_return;
|
||||
};
|
||||
coro();
|
||||
(void)received;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::core::lwt_init();
|
||||
|
||||
testGccUninitialized();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -10,9 +10,9 @@
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because __cpp_constexpr_dynamic_alloc < 201907L")
|
||||
int main() {}
|
||||
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1950
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1960
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC < 1950")
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC < 1960")
|
||||
int main() {}
|
||||
|
||||
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
|
||||
|
||||
Reference in New Issue
Block a user