Bug 86465 - [10/11/12/13 Regression] C++17 <optional> triggers: ‘<anonymous>’ may be used uninitialized in this function
Summary: [10/11/12/13 Regression] C++17 <optional> triggers: ‘<anonymous>’ may be used...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 9.0
: P2 normal
Target Milestone: 10.5
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2018-07-10 16:53 UTC by Pavel Roskin
Modified: 2022-09-22 13:11 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.5.0, 6.4.0
Known to fail: 7.3.0, 8.1.0, 8.2.0, 9.0
Last reconfirmed: 2019-06-12 00:00:00


Attachments
Preprocessed test case (76.09 KB, text/plain)
2018-07-10 16:53 UTC, Pavel Roskin
Details
Heavily simplified example, g++-5 compatible (23.30 KB, text/plain)
2018-09-27 21:48 UTC, Pavel Roskin
Details
Futher reduced example (281 bytes, text/plain)
2018-09-30 17:20 UTC, Pavel Roskin
Details
preprocessed source, unreduced, gzipped (243.13 KB, application/gzip)
2020-10-27 14:45 UTC, Jonathan Wakely
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pavel Roskin 2018-07-10 16:53:14 UTC
Created attachment 44378 [details]
Preprocessed test case

The attached file triggers a warning:

$ g++ -std=c++17 -Wall -O2 -c optional.cpp -save-temps
optional.cpp: In member function ‘virtual std::optional<int> Child::get_hairy_value()’:
optional.cpp:20:25: warning: ‘<anonymous>’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                 return {};
                         ^

The issue is observed with gcc 8 as packaged by Fedora (gcc-8.1.1-1.fc28.x86_64) and with the current gcc trunk (commit c85ec25b97e485c6f3493fc42c473db2a11ac9ea). gcc 7.3.0 doesn't exhibit the bug.

Interestingly, the preprocessed file generated by gcc 7.3.0 doesn't trigger the warning in gcc 8 or 9.

Also, the warning goes away if experimental/optional is used, so C++17 is required to reproduce it.

Optimization (at least -O1) is required to trigger the warning.
Comment 1 Jonathan Wakely 2018-07-11 10:10:40 UTC
Possibly related to PR 86485 (just a guess, I haven't investigated).
Comment 2 Pavel Roskin 2018-09-27 21:48:44 UTC
Created attachment 44761 [details]
Heavily simplified example, g++-5 compatible

I'm attaching a dumbed down version of the previous example, which compiles with gcc 5.5.0 and newer.

gcc 5.5.0 and gcc 6.4.0 don't produce any warning. gcc 7.3.0, 8.1.0 and the today's gcc from the git master branch all produce the warning.

That suggests that the issue is indeed related to the one described in bug #86485.

The implementation of optional in libstdc++ 7 doesn't trigger a warning, it's the changes in libstdc++ 8 that started triggering it. However, gcc 7 appears to have the same compiler issue.
Comment 3 Pavel Roskin 2018-09-30 17:20:37 UTC
Created attachment 44770 [details]
Futher reduced example

I was able to reduce the example to just 55 lines, removing almost all the code that came from the standard headers. The code complies with C++ standards all the way back to C++03.

As I suspected, the implementation of std::optional in libstdc++ uses a trick to avoid initializing the payload when the optional value default initialized, and that code turns out to be essential for reproducing the issue.

Try uncommenting _empty_char, and the warning goes away.
Comment 4 Jonathan Wakely 2019-06-12 15:47:14 UTC
This is taken from the libstdc++ testsuite:

#include <functional>
#include <assert.h>

int f1() { return 1; }
struct { int operator()() { return 2; } } f2;

void test01()
{
  typedef std::function<int()> function;

  function fo(f1);
  function fo1;
  fo1 = (std::move(fo));
  assert( static_cast<bool>(fo1) );
  assert( fo1() == 1 );

  fo = function(f2);
  function fo2;
  fo2 = (std::move(fo));
  assert( static_cast<bool>(fo2) );
  assert( fo2() == 2 );
}

int main()
{
  test01();
}

Since GCC 7 this gives warnings when -Wsystem-headers -Wuninitialized -O1 is used:


In file included from /xhome/jwakely/gcc/10/include/c++/10.0.0/bits/stl_function.h:60,
                 from /xhome/jwakely/gcc/10/include/c++/10.0.0/functional:49,
                 from uninit.cc:1:
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h: In function 'void test01()':
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h:193:7: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
  193 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h:192:11: warning: '<anonymous>' may be used uninitialized in this function [-Wmaybe-uninitialized]
  192 |       _Tp __tmp = _GLIBCXX_MOVE(__a);
      |           ^~~~~
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h:193:7: warning: '<anonymous>' may be used uninitialized in this function [-Wmaybe-uninitialized]
  193 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h:193:7: warning: '*((void*)&<anonymous> +24)' may be used uninitialized in this function [-Wmaybe-uninitialized]
  193 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/xhome/jwakely/gcc/10/include/c++/10.0.0/bits/move.h:193:7: warning: '<anonymous>' may be used uninitialized in this function [-Wmaybe-uninitialized]
  193 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~


valgrind and UBsan don't report any problems though.
Comment 5 Martin Sebor 2019-09-29 18:28:01 UTC
See also pr80635.
Comment 6 Richard Biener 2019-11-14 07:57:29 UTC
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
Comment 7 Jakub Jelinek 2020-03-04 09:38:40 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 8 Jeffrey A. Law 2020-03-05 21:30:32 UTC
Just a note, this is a distinct problem from pr80635.


Interestingly enough we get no useful output from the uninit pass.

AFAICT uninit is complaining about the various MEMs being potentially uninitialized.  Just taking the first instance as an example.  It's complaining about this statement in from bb2:

MEM[(union _Any_data * {ref-all})&fo] = MEM[(union _Any_data & {ref-all})&D.35879];

If we look at the entirety of BB2 we have:

<bb 2> [local count: 1073741824]:
MEM[(struct function *)&fo] ={v} {CLOBBER};
MEM[(struct _Function_base *)&fo] ={v} {CLOBBER};
MEM[(int (*<T24ca>) (void) *)&fo] = f1;
MEM[(struct function *)&fo1] ={v} {CLOBBER};
MEM[(struct _Function_base *)&fo1] ={v} {CLOBBER};
MEM[(struct _Function_base *)&D.35879] ={v} {CLOBBER};
__tmp = MEM[(union _Any_data & {ref-all})&fo];
MEM[(union _Any_data * {ref-all})&fo] = MEM[(union _Any_data & {ref-all})&D.35879];
MEM[(union _Any_data * {ref-all})&D.35879] = __tmp;
__tmp ={v} {CLOBBER};
MEM[(bool (*<T52d1>) (union _Any_data & {ref-all}, const union _Any_data & {ref-all}, _Manager_operation) &)&fo + 16] = 0B;
MEM[(int (*<T5c73>) (const union _Any_data & {ref-all}) &)&fo + 24] = SR.67_104(D);
__tmp = MEM[(union _Any_data & {ref-all})&D.35879];
MEM[(union _Any_data * {ref-all})&fo1] = __tmp;
__tmp ={v} {CLOBBER};
MEM[(bool (*<T52d1>) (union _Any_data & {ref-all}, const union _Any_data & {ref-all}, _Manager_operation) &)&fo1 + 16] = _M_manager;
MEM[(int (*<T5c73>) (const union _Any_data & {ref-all}) &)&fo1 + 24] = _M_invoke;
D.35879 ={v} {CLOBBER};
D.35879 ={v} {CLOBBER};
_8 = std::function<int()>::operator() (&fo1);

Note this clobber:

MEM[(struct _Function_base *)&D.35879] ={v} {CLOBBER};

The type is different than the statement we're complaining about:

MEM[(union _Any_data * {ref-all})&fo] = MEM[(union _Any_data & {ref-all})&D.35879];


I'm not sure if that's relevant.  I've never really dug into the uninit bits as they relate to memory references.
Comment 9 Jeffrey A. Law 2020-03-05 21:47:39 UTC
So from the uninit analyzer's standpoint the clobber isn't considered an initialization (which makes sense).  As a result the object really does appear to be uninitialized.

  struct function D.35879;

[ ... ]
  MEM[(struct function *)&fo] ={v} {CLOBBER};
  MEM[(struct _Function_base *)&fo] ={v} {CLOBBER};
  MEM[(int (*<T24ca>) (void) *)&fo] = f1;
  MEM[(struct function *)&fo1] ={v} {CLOBBER};
  MEM[(struct _Function_base *)&fo1] ={v} {CLOBBER};
  MEM[(struct _Function_base *)&D.35879] ={v} {CLOBBER};
  __tmp = MEM[(union _Any_data & {ref-all})&fo];
  MEM[(union _Any_data * {ref-all})&fo] = MEM[(union _Any_data & {ref-all})&D.35879];

That last statement reads from D.35879 which was never initialized
Comment 10 Jonathan Wakely 2020-10-27 14:45:56 UTC
Created attachment 49449 [details]
preprocessed source, unreduced, gzipped

Here's another example that produces this kind of warning, this time from the libstdc++ sources (when built with -Wsystem-headers -Werror)

It seems to be complaining about the std::allocator<char> object, which is an empty class so (1) who cares if it's uninitialized and (2) it's not uninitialized.

$ ~/gcc/11/bin/g++ -O2 -Wall cow-fs_path.ii -c      
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
In static member function ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:589:7,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:5151:30,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3620:9,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>::__sv_wrapper, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3541:65,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Tp&, const _Alloc&) [with _Tp = std::basic_string_view<char>; <template-parameter-2-2> = void; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3731:58,
    inlined from ‘std::filesystem::path::path(const _Source&, std::filesystem::path::format) [with _Source = std::basic_string_view<char>; _Require = std::filesystem::path]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9,
    inlined from ‘void std::filesystem::path::_M_concat(std::basic_string_view<char>)’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:340:24:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:604:36: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
  604 |         _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
      |                     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc: In member function ‘void std::filesystem::path::_M_concat(std::basic_string_view<char>)’:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:980:5: note: by argument 3 of type ‘const std::allocator<char>&’ to ‘static std::basic_string<_CharT, _Traits, _Alloc>::_Rep* std::basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_create(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ declared here
  980 |     basic_string<_CharT, _Traits, _Alloc>::_Rep::
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:44,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9: note: ‘<anonymous>’ declared here
  304 |       : _M_pathname(_S_convert(__detail::__effective_range(__source)))
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
In static member function ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:589:7,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:5151:30,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3620:9,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>::__sv_wrapper, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3541:65,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Tp&, const _Alloc&) [with _Tp = std::basic_string_view<char>; <template-parameter-2-2> = void; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3731:58,
    inlined from ‘std::filesystem::path::path(const _Source&, std::filesystem::path::format) [with _Source = char [2]; _Require = std::filesystem::path]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9,
    inlined from ‘std::filesystem::__detail::_Path<_Source>& std::filesystem::path::operator=(const _Source&) [with _Source = char [2]]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:340:24:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:604:36: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
  604 |         _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
      |                     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc: In function ‘std::filesystem::__detail::_Path<_Source>& std::filesystem::path::operator=(const _Source&) [with _Source = char [2]]’:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:980:5: note: by argument 3 of type ‘const std::allocator<char>&’ to ‘static std::basic_string<_CharT, _Traits, _Alloc>::_Rep* std::basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_create(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ declared here
  980 |     basic_string<_CharT, _Traits, _Alloc>::_Rep::
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:44,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9: note: ‘<anonymous>’ declared here
  304 |       : _M_pathname(_S_convert(__detail::__effective_range(__source)))
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
In static member function ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:589:7,
    inlined from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:5151:30,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3620:9,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>::__sv_wrapper, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3541:65,
    inlined from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Tp&, const _Alloc&) [with _Tp = std::basic_string_view<char>; <template-parameter-2-2> = void; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3731:58,
    inlined from ‘std::filesystem::path::path(const _Source&, std::filesystem::path::format) [with _Source = std::basic_string_view<char>; _Require = std::filesystem::path]’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9,
    inlined from ‘void std::filesystem::path::_M_append(std::basic_string_view<char>)’ at /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:340:24:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:604:36: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
  604 |         _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
      |                     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/string:55,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/stdexcept:38,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/system_error:40,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_fwd.h:35,
                 from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:43,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc: In member function ‘void std::filesystem::path::_M_append(std::basic_string_view<char>)’:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:980:5: note: by argument 3 of type ‘const std::allocator<char>&’ to ‘static std::basic_string<_CharT, _Traits, _Alloc>::_Rep* std::basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_create(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ declared here
  980 |     basic_string<_CharT, _Traits, _Alloc>::_Rep::
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/filesystem:44,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/fs_path.cc:34,
                 from /home/jwakely/src/gcc/libstdc++-v3/src/c++17/cow-fs_path.cc:26:
/home/jwakely/build/powerpc64le-unknown-linux-gnu/libstdc++-v3/include/bits/fs_path.h:304:9: note: ‘<anonymous>’ declared here
  304 |       : _M_pathname(_S_convert(__detail::__effective_range(__source)))
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 11 Jonathan Wakely 2020-11-16 21:09:47 UTC
(In reply to Jonathan Wakely from comment #10)
> Created attachment 49449 [details]
> preprocessed source, unreduced, gzipped
> 
> Here's another example that produces this kind of warning, this time from
> the libstdc++ sources (when built with -Wsystem-headers -Werror)
> 
> It seems to be complaining about the std::allocator<char> object, which is
> an empty class so (1) who cares if it's uninitialized and (2) it's not
> uninitialized.

That one seems to be the same as PR 97840
Comment 12 Jason Merrill 2021-04-08 16:08:02 UTC
Changing component.
Comment 13 Jakub Jelinek 2021-05-14 09:50:42 UTC
GCC 8 branch is being closed.
Comment 14 Richard Biener 2021-06-01 08:11:53 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 15 Geoff 2022-01-12 09:59:18 UTC
This appears to still be an issue in gcc 11.2 minimal reproduced example using std::optional https://godbolt.org/z/ebbMe3Wva


std::optional<bool> empty_optional(int x){
    return {};
}

std::optional<bool> empty_optional_or_true(int x){
    if(x > 0){
        return std::make_optional(true);
    }
    return {}; // <- second here
}

int main(){
empty_optional_or_true
}
Comment 16 Geoff 2022-01-12 10:16:59 UTC
This appears to still be an issue in gcc 11.2 minimal reproduced example using std::optional https://godbolt.org/z/ebbMe3Wva.

-std=c++17 -O3 -fsanitize=address -Wall -Werror -Wno-unused

std::optional<bool> empty_optional_or_true(int x){
    if(x > 0){
        return std::make_optional(true);
    }
    return {};
    //      ^ error here
}

int main(){
    empty_optional_or_true(0)
}

------------

In function 'std::optional<bool> empty_optional_or_true(int)',
    inlined from 'std::optional<bool> empty_optional_or_true(int)' at <source>:28:21:
<source>:7:13: error: '*(unsigned char*)((char*)&<unnamed> + offsetof(std::optional<bool>,std::optional<bool>::<unnamed>.std::_Optional_base<bool, true, true>::<unnamed>))' may be used uninitialized [-Werror=maybe-uninitialized]
    7 |     return {};
      |             ^
<source>: In function 'std::optional<bool> empty_optional_or_true(int)':
<source>:7:13: note: '<anonymous>' declared here
    7 |     return {}; // <- second here
      |    

In the linked example it can be see that making the global function static or wrapping it in an anonymous namespace will cause the error to disappear.
Comment 17 Marc Nieper-Wißkirchen 2022-01-12 10:22:57 UTC
Does a viable workaround exist that doesn't amount to disabling the warning option altogether?

In my case, the actual warning is triggered inside the standard library, which is used by my code that uses std::optional.

Thanks.
Comment 18 Marc Nieper-Wißkirchen 2022-01-12 12:12:10 UTC
Does a viable workaround exist that doesn't amount to disabling the warning option altogether?

In my case, the actual warning is triggered inside the standard library, which is used by my code that uses std::optional.

Thanks.
Comment 19 Richard Biener 2022-05-27 09:39:18 UTC
GCC 9 branch is being closed
Comment 20 Jakub Jelinek 2022-06-28 10:35:34 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 21 Richard Biener 2022-09-22 13:11:48 UTC
The original, the heavy simplified and Jonathans example no longer reproduce diagnostics for me on any active branch.  The latest reported issue still is diagnosed with -fsanitize=address but that's a different issue.

So let's close this.