https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109561
Bug ID: 109561 Summary: -Wmaybe-uninitialized false positive false positive false positive false positive false positive Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: f.heckenb...@fh-soft.de Target Milestone: --- (code and error below) I don't know how to put this nicely, this is a terrible message: - Most of it consists of standard library internals. - The actual message ("may be used uninitialized") is buried well within it and also refers to internal fields. - It is reported no less than 5 times!? - Most of all, AFAICS, it's bogus. The default constructor of std::optional should construct an object that does not contain a value and such objects can be copied just fine. - Like many such bogus warnings apparently, it's rather volatile. Unrelated changes, e.g. to i or removing the defaulted constructor declaration, can make it disappear. Producing this minimal example was a lot of guesswork what can be removed in which order without disturbing the message. - It's a regression from 10.2.1 and 11.3. % cat test.cpp #include <optional> #include <vector> #include <string> struct O { std::optional <int> i; std::optional <std::string> s; O () = default; }; std::vector <O> a; void f () { for (auto &i: a) i = { }; } % g++ --std=c++20 -O2 -Wall -c test.cpp In file included from /usr/include/c++/12/string:53, from test.cpp:3: In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::pointer std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_data() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’, inlined from ‘constexpr bool std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_is_local() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:274:23, inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:859:23, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:194:19, inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>& std::_Optional_payload<_Tp, true, false, false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:420:22, inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>& std::_Optional_payload<_Tp, false, _Copy, _Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp = std::__cxx11::basic_string<char>; bool _Copy = false; bool _Move = false]’ at /usr/include/c++/12/optional:436:26, inlined from ‘constexpr std::_Optional_base<_Tp, <anonymous>, <anonymous> >& std::_Optional_base<_Tp, <anonymous>, <anonymous> >::operator=(std::_Optional_base<_Tp, <anonymous>, <anonymous> >&&) [with _Tp = std::__cxx11::basic_string<char>; bool <anonymous> = false; bool <anonymous> = false]’ at /usr/include/c++/12/optional:550:23, inlined from ‘constexpr std::optional<std::__cxx11::basic_string<char> >& std::optional<std::__cxx11::basic_string<char> >::operator=(std::optional<std::__cxx11::basic_string<char> >&&)’ at /usr/include/c++/12/optional:705:11, inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8, inlined from ‘void f()’ at test.cpp:17:11: /usr/include/c++/12/bits/basic_string.h:234:28: warning: ‘*(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)((char*)&<unnamed> + offsetof(O, O::s.std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<unnamed>.std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false, false>::<unnamed>)).std::__cxx11::basic_string<char>::_M_dataplus.std::__cxx11::basic_string<char>::_Alloc_hider::_M_p’ may be used uninitialized [-Wmaybe-uninitialized] 234 | { return _M_dataplus._M_p; } | ^~~~ test.cpp: In function ‘void f()’: test.cpp:17:11: note: ‘<anonymous>’ declared here 17 | i = { }; | ^ In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’, inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:866:17, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:194:19, inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>& std::_Optional_payload<_Tp, true, false, false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:420:22, inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>& std::_Optional_payload<_Tp, false, _Copy, _Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp = std::__cxx11::basic_string<char>; bool _Copy = false; bool _Move = false]’ at /usr/include/c++/12/optional:436:26, inlined from ‘constexpr std::_Optional_base<_Tp, <anonymous>, <anonymous> >& std::_Optional_base<_Tp, <anonymous>, <anonymous> >::operator=(std::_Optional_base<_Tp, <anonymous>, <anonymous> >&&) [with _Tp = std::__cxx11::basic_string<char>; bool <anonymous> = false; bool <anonymous> = false]’ at /usr/include/c++/12/optional:550:23, inlined from ‘constexpr std::optional<std::__cxx11::basic_string<char> >& std::optional<std::__cxx11::basic_string<char> >::operator=(std::optional<std::__cxx11::basic_string<char> >&&)’ at /usr/include/c++/12/optional:705:11, inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8, inlined from ‘void f()’ at test.cpp:17:11: /usr/include/c++/12/bits/basic_string.h:1064:16: warning: ‘*(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)((char*)&<unnamed> + offsetof(O, O::s.std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<unnamed>.std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false, false>::<unnamed>)).std::__cxx11::basic_string<char>::_M_string_length’ may be used uninitialized [-Wmaybe-uninitialized] 1064 | { return _M_string_length; } | ^~~~~~~~~~~~~~~~ test.cpp: In function ‘void f()’: test.cpp:17:11: note: ‘<anonymous>’ declared here 17 | i = { }; | ^ In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’, inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:866:17, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:194:19, inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>& std::_Optional_payload<_Tp, true, false, false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:420:22, inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>& std::_Optional_payload<_Tp, false, _Copy, _Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp = std::__cxx11::basic_string<char>; bool _Copy = false; bool _Move = false]’ at /usr/include/c++/12/optional:436:26, inlined from ‘constexpr std::_Optional_base<_Tp, <anonymous>, <anonymous> >& std::_Optional_base<_Tp, <anonymous>, <anonymous> >::operator=(std::_Optional_base<_Tp, <anonymous>, <anonymous> >&&) [with _Tp = std::__cxx11::basic_string<char>; bool <anonymous> = false; bool <anonymous> = false]’ at /usr/include/c++/12/optional:550:23, inlined from ‘constexpr std::optional<std::__cxx11::basic_string<char> >& std::optional<std::__cxx11::basic_string<char> >::operator=(std::optional<std::__cxx11::basic_string<char> >&&)’ at /usr/include/c++/12/optional:705:11, inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8, inlined from ‘void f()’ at test.cpp:17:11: /usr/include/c++/12/bits/basic_string.h:1064:16: warning: ‘*(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)((char*)&<unnamed> + offsetof(O, O::s.std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<unnamed>.std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false, false>::<unnamed>)).std::__cxx11::basic_string<char>::_M_string_length’ may be used uninitialized [-Wmaybe-uninitialized] 1064 | { return _M_string_length; } | ^~~~~~~~~~~~~~~~ test.cpp: In function ‘void f()’: test.cpp:17:11: note: ‘<anonymous>’ declared here 17 | i = { }; | ^ In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::length() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’, inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:676:22, inlined from ‘constexpr void std::_Construct(_Tp*, _Args&& ...) [with _Tp = __cxx11::basic_string<char>; _Args = {__cxx11::basic_string<char, char_traits<char>, allocator<char> >}]’ at /usr/include/c++/12/bits/stl_construct.h:119:7, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_construct(_Args&& ...) [with _Args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:278:19, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:198:26, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:189:7, inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>& std::_Optional_payload<_Tp, true, false, false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:420:22, inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>& std::_Optional_payload<_Tp, false, _Copy, _Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp = std::__cxx11::basic_string<char>; bool _Copy = false; bool _Move = false]’ at /usr/include/c++/12/optional:436:26, inlined from ‘constexpr std::_Optional_base<_Tp, <anonymous>, <anonymous> >& std::_Optional_base<_Tp, <anonymous>, <anonymous> >::operator=(std::_Optional_base<_Tp, <anonymous>, <anonymous> >&&) [with _Tp = std::__cxx11::basic_string<char>; bool <anonymous> = false; bool <anonymous> = false]’ at /usr/include/c++/12/optional:550:23, inlined from ‘constexpr std::optional<std::__cxx11::basic_string<char> >& std::optional<std::__cxx11::basic_string<char> >::operator=(std::optional<std::__cxx11::basic_string<char> >&&)’ at /usr/include/c++/12/optional:705:11, inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8, inlined from ‘void f()’ at test.cpp:17:11: /usr/include/c++/12/bits/basic_string.h:1071:16: warning: ‘*(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)((char*)&<unnamed> + offsetof(O, O::s.std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<unnamed>.std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false, false>::<unnamed>)).std::__cxx11::basic_string<char>::_M_string_length’ may be used uninitialized [-Wmaybe-uninitialized] 1071 | { return _M_string_length; } | ^~~~~~~~~~~~~~~~ test.cpp: In function ‘void f()’: test.cpp:17:11: note: ‘<anonymous>’ declared here 17 | i = { }; | ^ In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::length() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’, inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:676:22, inlined from ‘constexpr void std::_Construct(_Tp*, _Args&& ...) [with _Tp = __cxx11::basic_string<char>; _Args = {__cxx11::basic_string<char, char_traits<char>, allocator<char> >}]’ at /usr/include/c++/12/bits/stl_construct.h:119:7, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_construct(_Args&& ...) [with _Args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:278:19, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:198:26, inlined from ‘constexpr void std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:189:7, inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>& std::_Optional_payload<_Tp, true, false, false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp = std::__cxx11::basic_string<char>]’ at /usr/include/c++/12/optional:420:22, inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>& std::_Optional_payload<_Tp, false, _Copy, _Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp = std::__cxx11::basic_string<char>; bool _Copy = false; bool _Move = false]’ at /usr/include/c++/12/optional:436:26, inlined from ‘constexpr std::_Optional_base<_Tp, <anonymous>, <anonymous> >& std::_Optional_base<_Tp, <anonymous>, <anonymous> >::operator=(std::_Optional_base<_Tp, <anonymous>, <anonymous> >&&) [with _Tp = std::__cxx11::basic_string<char>; bool <anonymous> = false; bool <anonymous> = false]’ at /usr/include/c++/12/optional:550:23, inlined from ‘constexpr std::optional<std::__cxx11::basic_string<char> >& std::optional<std::__cxx11::basic_string<char> >::operator=(std::optional<std::__cxx11::basic_string<char> >&&)’ at /usr/include/c++/12/optional:705:11, inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8, inlined from ‘void f()’ at test.cpp:17:11: /usr/include/c++/12/bits/basic_string.h:1071:16: warning: ‘*(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)((char*)&<unnamed> + offsetof(O, O::s.std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<unnamed>.std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false, false>::<unnamed>)).std::__cxx11::basic_string<char>::_M_string_length’ may be used uninitialized [-Wmaybe-uninitialized] 1071 | { return _M_string_length; } | ^~~~~~~~~~~~~~~~ test.cpp: In function ‘void f()’: test.cpp:17:11: note: ‘<anonymous>’ declared here 17 | i = { }; | ^