https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106922
Bug ID: 106922 Summary: [12 Regression] Bogus uninitialized warning on boost::optional<<std::vector<std::string>>> Product: gcc Version: 12.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jan.zizka at nokia dot com Target Milestone: --- Created attachment 53568 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53568&action=edit Reproducer for maybe uninitialized warning with gcc 12 In our production code when upgrading to gcc 12 from gcc 11 we have faced bogus warning "may be used uninitialized" on bit complex use of boost::optional vector of strings used in a loop with unrelated string stream redirect. > In file included from <..>/include/c++/12.0.0/vector:67, > from reproduce.cpp:13: > In destructor ‘std::vector<_Tp, _Alloc>::~vector() [with _Tp = > std::__cxx11::basic_string<char>; _Alloc = > std::allocator<std::__cxx11::basic_string<char> >]’, > inlined from ‘void > boost::optional_detail::optional_base<T>::destroy_impl() [with T = > std::vector<std::__cxx11::basic_string<char> >]’ at > /usr/include/boost/optional/optional.hpp:771:50, > inlined from ‘void boost::optional_detail::optional_base<T>::destroy() > [with T = std::vector<std::__cxx11::basic_string<char> >]’ at > /usr/include/boost/optional/optional.hpp:757:21, > inlined from ‘void boost::optional_detail::optional_base<T>::assign(const > boost::optional_detail::optional_base<T>&) [with T = > std::vector<std::__cxx11::basic_string<char> >]’ at > /usr/include/boost/optional/optional.hpp:264:21, > inlined from ‘boost::optional_detail::optional_base<T>& > boost::optional_detail::optional_base<T>::operator=(const > boost::optional_detail::optional_base<T>&) [with T = > std::vector<std::__cxx11::basic_string<char> >]’ at > /usr/include/boost/optional/optional.hpp:241:19, > inlined from ‘boost::optional<T>& boost::optional<T>::operator=(const > boost::optional<T>&) [with T = std::vector<std::__cxx11::basic_string<char> > >]’ at /usr/include/boost/optional/optional.hpp:1040:15, > inlined from ‘void test()’ at reproduce.cpp:55:13: > <..>/include/c++/12.0.0/bits/stl_vector.h:680:22: error: > ‘*(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > > >*)((char*)&external + > offsetof(boost::Optional<std::vector<std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >, > std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > > > > >,boost::optional<std::vector<std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >, > std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > > > > >::<unnamed>.boost::optional_detail::optional_base<std::vector<std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >, > std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > > > > >::m_storage.boost::optional_detail::aligned_storage<std::vector<std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >, > std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > > > > >::dummy_)).std::vector<std::__cxx11::basic_string<char> > >::<anonymous>.std::_Vector_base<std::__cxx11::basic_string<char>, > std::allocator<std::__cxx11::basic_string<char> > > >::_M_impl.std::_Vector_base<std::__cxx11::basic_string<char>, > std::allocator<std::__cxx11::basic_string<char> > > >::_Vector_impl::<anonymous>.std::_Vector_base<std::__cxx11::basic_string<char>, > std::allocator<std::__cxx11::basic_string<char> > > >::_Vector_impl_data::_M_finish’ may be used uninitialized > [-Werror=maybe-uninitialized] > 680 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, > | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 681 | _M_get_Tp_allocator()); > | ~~~~~~~~~~~~~~~~~~~~~~ > reproduce.cpp: In function ‘void test()’: > reproduce.cpp:45:40: note: ‘external’ declared here > 45 | Optional<std::vector<std::string>> external; > | ^~~~~~~~ I have tested this with gcc 12 (12.1.1, 12.2.1 and release/gcc-12 commit https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=4ce316ca54c863cf0fd4257ba0ab768ab83c62e5") with boost 1.69.0, 1.75.0, 1.76.0 and 1.80.0. All fails. With any boost version and gcc 11 (11.3.1 and release/gcc-11 tip commit https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=7e356c3083c79473c941bc92d61f755e923bc86c) the warning doesn't appear. To reproduce: > $ g++ -Werror -std=c++20 -O2 -Wall -o reproduce.o -c reproduce.cpp I was not able to bump the reproducer to simpliear case. In all modification where loop is removed the warning disappears. The problem doesn't occur when std::optional is used. Only workaround I found is to add following pragma at top of the module: > #pragma GCC diagnostic push > #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" > #include <vector> > #pragma GCC diagnostic pop I have bisected the problem to start with https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=5b8b1522e04adc20980f396571be1929a32d148a commit 5b8b1522e04adc20980f396571be1929a32d148a (HEAD, refs/bisect/bad) Author: Richard Biener <rguent...@suse.de> Date: Mon Sep 27 12:01:38 2021 +0200 tree-optimization/100112 - VN last_vuse and redundant store elimination This avoids the last_vuse optimization hindering redundant store elimination by always also recording the original VUSE that was in effect on the load. In stage3 gcc/*.o we have 3182752 times recorded a single entry and 903409 times two entries (that's ~20% overhead). With just recording a single entry the number of hashtable lookups done when walking the vuse->vdef links to find an earlier access is 28961618. When recording the second entry this makes us find that earlier for donwnstream redundant accesses, reducing the number of hashtable lookups to 25401052 (that's a ~10% reduction). 2021-09-27 Richard Biener <rguent...@suse.de> PR tree-optimization/100112 * tree-ssa-sccvn.c (visit_reference_op_load): Record the referece into the hashtable twice in case last_vuse is different from the original vuse on the stmt. * gcc.dg/tree-ssa/ssa-fre-95.c: New testcase.