Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix all gcc-13 -Wmaybe-uninitialized warnings #119

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
8 changes: 5 additions & 3 deletions include/boost/optional/detail/optional_aligned_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class aligned_storage
// BOOST_MAY_ALIAS works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
union BOOST_MAY_ALIAS dummy_u
{
dummy_u(){}
~dummy_u(){}
unsigned char data[ sizeof(T) ];
BOOST_DEDUCED_TYPENAME type_with_alignment<
::boost::alignment_of<T>::value >::type aligner_;
Expand Down Expand Up @@ -60,9 +62,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 @@ -39,7 +39,7 @@ class tc_optional_base : public optional_tag

tc_optional_base ( none_t )
:
m_initialized(false) {}
m_initialized(false), m_storage() {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a write that will never be read.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I understand now. I thought you were still using the union here as a form of aligned_storage.

There is a write here because m_storage is actually a T, not a union { T t_ }

You know what this means? It means that the maybe-uninitialized warning truly is genuine then!

If an optional is constructed with none and then copied, we're technically copying uninitialized values.

My first instinct would be to simply update this code to store a union but I'm not sure what the goals of this trivially copyable base specialization is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I have an idea:

struct zst{};
union tc_storage { T t_; zst z_; };

  private :

    bool m_initialized ;
    tc_storage m_storage ;

Then whenever we need default constructibility, we just do: m_storage.z_={};

Exactly like this:

tc_optional_base ( none_t )
  :
  m_initialized(false) {
    m_storage.z_={};
  }


tc_optional_base ( init_value_tag, argument_type val )
:
Expand Down Expand Up @@ -497,8 +497,8 @@ class tc_optional_base : public optional_tag
m_initialized = false;
}

reference_const_type get_impl() const { return m_storage ; }
reference_type get_impl() { return m_storage ; }
reference_const_type get_impl() const { return *boost::core::launder(&m_storage) ; }
reference_type get_impl() { return *boost::core::launder(&m_storage) ; }

pointer_const_type get_ptr_impl() const { return boost::addressof(m_storage); }
pointer_type get_ptr_impl() { return boost::addressof(m_storage); }
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