Skip to content

Commit

Permalink
Fix some -Wmaybe-uninitialized warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
akrzemi1 committed Dec 29, 2023
1 parent c60db27 commit e31cf6f
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 58 deletions.
7 changes: 6 additions & 1 deletion doc/91_relnotes.qbk
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
Expand Down
104 changes: 52 additions & 52 deletions include/boost/optional/detail/old_optional_implementation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
{
#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
BOOST_STATIC_ASSERT_MSG(
!boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
!boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
"binding rvalue references to optional lvalue references is disallowed");
#endif
#endif
}

struct optional_tag {} ;
Expand Down Expand Up @@ -222,7 +222,7 @@ class optional_base : public optional_tag
construct(rhs.get_impl());
}
}

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value)
void assign ( optional_base&& rhs )
Expand All @@ -239,7 +239,7 @@ class optional_base : public optional_tag
construct(boost::move(rhs.get_impl()));
}
}
#endif
#endif

// Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
template<class U>
Expand All @@ -253,7 +253,7 @@ class optional_base : public optional_tag
#else
assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
#endif

else destroy();
}
else
Expand Down Expand Up @@ -286,15 +286,15 @@ class optional_base : public optional_tag
}
}
#endif

// Assigns from a T (deep-copies the rhs value)
void assign ( argument_type val )
{
if (is_initialized())
assign_value(val, is_reference_predicate() );
else construct(val);
}

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from a T (deep-moves the rhs value)
void assign ( rval_reference_type val )
Expand Down Expand Up @@ -355,7 +355,7 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type(val) ;
m_initialized = true ;
}

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void construct ( rval_reference_type val )
{
Expand Down Expand Up @@ -383,7 +383,7 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
m_initialized = true ;
}

void emplace_assign ()
{
destroy();
Expand All @@ -398,15 +398,15 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type( arg );
m_initialized = true ;
}

template<class Arg>
void emplace_assign ( Arg& arg )
{
destroy();
::new (m_storage.address()) internal_type( arg );
m_initialized = true ;
}

void emplace_assign ()
{
destroy();
Expand Down Expand Up @@ -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() ; }

Expand Down Expand Up @@ -677,7 +677,7 @@ class optional : public optional_detail::optional_base<T>
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates an optional<T> initialized with 'move(val)'.
// Can throw if T::T(T &&) does
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
#endif

Expand All @@ -698,7 +698,7 @@ class optional : public optional_detail::optional_base<T>
if ( rhs.is_initialized() )
this->construct(rhs.get());
}

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates a deep move of another convertible optional<U>
// Requires a valid conversion from U to T.
Expand Down Expand Up @@ -727,12 +727,12 @@ class optional : public optional_detail::optional_base<T>


template<class Expr>
explicit optional ( Expr&& expr,
explicit optional ( Expr&& expr,
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
(boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value, bool >::type = true
)
: base(boost::forward<Expr>(expr),boost::addressof(expr))
(boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value, bool >::type = true
)
: base(boost::forward<Expr>(expr),boost::addressof(expr))
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();}

#else
Expand Down Expand Up @@ -764,10 +764,10 @@ class optional : public optional_detail::optional_base<T>

template<class Expr>
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value,
optional&
>::type
>::type
operator= ( Expr&& expr )
{
optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();
Expand All @@ -794,7 +794,7 @@ class optional : public optional_detail::optional_base<T>
this->assign(rhs);
return *this ;
}

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
// Requires a valid conversion from U to T.
Expand All @@ -818,7 +818,7 @@ class optional : public optional_detail::optional_base<T>

#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value)
optional& operator= ( optional && rhs )
optional& operator= ( optional && rhs )
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
{
this->assign( static_cast<base &&>(rhs) ) ;
Expand Down Expand Up @@ -852,7 +852,7 @@ class optional : public optional_detail::optional_base<T>
this->assign( none_ ) ;
return *this ;
}

#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// Constructs in-place
// upon exception *this is always uninitialized
Expand All @@ -867,7 +867,7 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( boost::forward<Arg>(arg) );
}

void emplace ()
{
this->emplace_assign();
Expand All @@ -878,13 +878,13 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( arg );
}

template<class Arg>
void emplace ( Arg& arg )
{
this->emplace_assign( arg );
}

void emplace ()
{
this->emplace_assign();
Expand Down Expand Up @@ -918,7 +918,7 @@ class optional : public optional_detail::optional_base<T>
// Returns a reference to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED
// No-throw
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
reference_const_type operator *() const& { return this->get() ; }
reference_type operator *() & { return this->get() ; }
reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
Expand All @@ -927,42 +927,42 @@ class optional : public optional_detail::optional_base<T>
reference_type operator *() { return this->get() ; }
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS

#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
reference_const_type value() const&
{
{
if (this->is_initialized())
return this->get() ;
else
throw_exception(bad_optional_access());
}

reference_type value() &
{
{
if (this->is_initialized())
return this->get() ;
else
throw_exception(bad_optional_access());
}

reference_type_of_temporary_wrapper value() &&
{
{
if (this->is_initialized())
return base::types::move(this->get()) ;
else
throw_exception(bad_optional_access());
}

#else
#else
reference_const_type value() const
{
{
if (this->is_initialized())
return this->get() ;
else
throw_exception(bad_optional_access());
}

reference_type value()
{
{
if (this->is_initialized())
return this->get() ;
else
Expand All @@ -974,24 +974,24 @@ class optional : public optional_detail::optional_base<T>
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
template <class U>
value_type value_or ( U&& v ) const&
{
{
if (this->is_initialized())
return get();
else
return boost::forward<U>(v);
}

template <class U>
value_type value_or ( U&& v ) &&
{
value_type value_or ( U&& v ) &&
{
if (this->is_initialized())
return base::types::move(get());
else
return boost::forward<U>(v);
}
#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template <class U>
value_type value_or ( U&& v ) const
value_type value_or ( U&& v ) const
{
if (this->is_initialized())
return get();
Expand All @@ -1000,17 +1000,17 @@ class optional : public optional_detail::optional_base<T>
}
#else
template <class U>
value_type value_or ( U const& v ) const
{
value_type value_or ( U const& v ) const
{
if (this->is_initialized())
return get();
else
return v;
}

template <class U>
value_type value_or ( U& v ) const
{
value_type value_or ( U& v ) const
{
if (this->is_initialized())
return get();
else
Expand All @@ -1028,7 +1028,7 @@ class optional : public optional_detail::optional_base<T>
else
return f();
}

template <typename F>
value_type value_or_eval ( F f ) &&
{
Expand All @@ -1047,9 +1047,9 @@ class optional : public optional_detail::optional_base<T>
return f();
}
#endif

bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }

BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
} ;

Expand Down
6 changes: 3 additions & 3 deletions include/boost/optional/detail/optional_aligned_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ 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()); }

} ;

} // namespace optional_detail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
:
Expand Down
1 change: 1 addition & 0 deletions include/boost/optional/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Loading

0 comments on commit e31cf6f

Please sign in to comment.