Fix some -Wmaybe-uninitialized warnings

This commit is contained in:
Andrzej Krzemienski
2023-12-29 01:40:01 +01:00
parent c60db27762
commit e31cf6f2a8
7 changed files with 221 additions and 58 deletions

View File

@ -1,7 +1,7 @@
[/
Boost.Optional
Copyright (c) 2015 - 2022 Andrzej Krzemienski
Copyright (c) 2015 - 2023 Andrzej Krzemienski
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@ -11,6 +11,11 @@
[section:relnotes Release Notes]
[heading Boost Release 1.85]
* Fixed the implementation for trivial types. Now it is slower, because it always initializes the `T`, but it avoids undefined behavior when `optional<T>` is copied. This fixes [@https://github.com/boostorg/optional/issues/108 issue #108].
* Fixed some `-Wmaybe-uninitialized` warnings in GCC 12. Thanks to Christian Mazakas for the fix.
[heading Boost Release 1.83]
* Deprecated support for C++03 and earlier, C++11 will be required in release 1.86.

View File

@ -615,8 +615,8 @@ class optional_base : public optional_tag
#endif
// reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *boost::core::launder(p) ; }
reference_type dereference( internal_type* p, is_not_reference_tag ) { return *boost::core::launder(p) ; }
reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }

View File

@ -60,8 +60,8 @@ class aligned_storage
T * ptr_ref() { return static_cast<T *> (address()); }
#endif
T const& ref() const { return *ptr_ref(); }
T & ref() { return *ptr_ref(); }
T const& ref() const { return *boost::core::launder(ptr_ref()); }
T & ref() { return *boost::core::launder(ptr_ref()); }
} ;

View File

@ -35,11 +35,11 @@ class tc_optional_base : public optional_tag
tc_optional_base()
:
m_initialized(false) {}
m_initialized(false), m_storage() {}
tc_optional_base ( none_t )
:
m_initialized(false) {}
m_initialized(false), m_storage() {}
tc_optional_base ( init_value_tag, argument_type val )
:

View File

@ -31,6 +31,7 @@
#include <boost/core/enable_if.hpp>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/launder.hpp>
#include <boost/optional/bad_optional_access.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>

View File

@ -20,6 +20,7 @@ import testing ;
[ run optional_test.cpp ]
[ run optional_test_assign.cpp ]
[ run optional_test_swap.cpp ]
[ compile optional_test_wuninitialized.cpp ]
[ run optional_test_conversions_from_U.cpp ]
[ run optional_test_convert_from_T.cpp ]
[ run optional_test_convert_assign.cpp ]

View File

@ -0,0 +1,156 @@
// Copyright (C) 2023 Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
// This is a minimum example that reproduces the -Wmaybe-Uninitialized
// warning in GCC 12
#include "boost/optional/optional.hpp"
#include "boost/none.hpp"
#include "boost/core/lightweight_test.hpp"
using boost::optional ;
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::get ;
using boost::get_pointer ;
#endif
bool throw_on_assign = false;
int count = 0;
class X
{
public :
X ( int av = 0) : v(av)
{
++ count ;
}
X ( X const& rhs ) : v(rhs.v)
{
}
~X()
{
-- count ;
}
X& operator= ( X const& rhs )
{
if ( throw_on_assign )
{
v = rhs.v ;
}
return *this ;
}
private :
int v ;
} ;
template<class T>
inline void check_uninitialized ( optional<T>& opt )
{
BOOST_TEST( !opt.get_ptr() ) ;
BOOST_TEST( !opt.get_ptr() ) ;
BOOST_TEST( opt.is_initialized()) ;
BOOST_TEST( opt.is_initialized() ) ;
BOOST_TEST( opt.is_initialized() ) ;
BOOST_TEST( opt.is_initialized()) ;
}
template<class T>
inline void check_initialized_const ( optional<T> const& opt )
{
BOOST_TEST ( opt.get_ptr() ) ;
BOOST_TEST ( opt.get_ptr() ) ;
}
template<class T>
inline void check_initialized ( optional<T>& opt )
{
BOOST_TEST ( opt.get_ptr() ) ;
BOOST_TEST ( opt.get_ptr() ) ;
BOOST_TEST ( opt.has_value() ) ;
BOOST_TEST ( opt.has_value() ) ;
BOOST_TEST( opt.has_value() ) ;
BOOST_TEST ( opt.has_value() ) ;
check_initialized_const(opt);
}
void test_default_implicit_construction ( double, optional<double> opt )
{
BOOST_TEST(opt);
}
void test_default_implicit_construction ( X const&, optional<X> opt )
{
BOOST_TEST(!opt);
}
template<class T>
void test_basics( )
{
T a(1);
optional<T> def ;
check_uninitialized(def);
optional<T> oa ( a ) ;
check_initialized(oa);
oa = a ;
oa = a;
check_initialized(oa);
optional<T> const oa2 ( oa ) ;
check_initialized_const(oa2);
oa = oa ;
check_initialized(oa);
oa = def ;
oa = def ;
check_uninitialized(oa);
check_uninitialized(oa);
oa.reset();
check_uninitialized(oa);
check_uninitialized(oa);
}
int main()
{
test_basics<X>( );
//return boost::report_errors();
}