Initialize gdb::optional empty payload to quiet false -Wmaybe-uninitialized warnings

Commit ecfb656c37 ("dwarf2read.c: Make dir_index and
file_name_index strong typedefs") added a use of gdb::optional that
triggers bogus -Wmaybe-uninitialized warnings:

GCC trunk is complaining like this:

  ../../binutils-gdb/gdb/dwarf2read.c: In function void read_formatted_entries(bfd*, const gdb_byte**, line_header*, const comp_unit_head*, void (*)(line_header*, const char*, dir_index, unsigned int, unsigned int)):
  ../../binutils-gdb/gdb/dwarf2read.c:17779:65: error: fe.file_entry::length may be used uninitialized in this function [-Werror=maybe-uninitialized]
	 callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
								   ^
  ../../binutils-gdb/gdb/dwarf2read.c:17779:65: error: *((void*)& fe +8) may be used uninitialized in this function [-Werror=maybe-uninitialized]
  ../../binutils-gdb/gdb/dwarf2read.c:17779:65: error: fe.file_entry::mod_time may be used uninitialized in this function [-Werror=maybe-uninitialized]
  ../../binutils-gdb/gdb/dwarf2read.c:17779:65: error: fe.file_entry::name may be used uninitialized in this function [-Werror=maybe-uninitialized]

While some older GCCs are complaining like this:

  ../../binutils-gdb/gdb/dwarf2read.c: In function void read_formatted_entries(bfd*, const gdb_byte**, line_header*, const comp_unit_head*, void (*)(line_header*, const char*, dir_index, unsigned int, unsigned int)):
  ../../binutils-gdb/gdb/dwarf2read.c:17779:65: error: uint may be used uninitialized in this function [-Werror=maybe-uninitialized]
	 callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);

Looking around the web, I see that boost's optional implementation
triggers this kind of issue often too.  See:

  http://www.boost.org/doc/libs/1_63_0/libs/optional/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html

I noticed that replacing the gdb::optional uses with real C++17
std::optional uses against GCC 7/trunk makes the warnings go away.
Looking at the implementation, AFAICS, libstdc++ always initializes
its "empty" union payload member (_M_empty, which is defined as an
empty class, like ours).  I.e., all payload types have this ctor:

    struct _Optional_payload.....
    {
      constexpr _Optional_payload()
	: _M_empty() {}

The constexpr makes a diference too.  Without it, GCC7 still warns.

So I'm applying the same treatment to our gdb::optional.

gdb/ChangeLog:
2017-04-05  Pedro Alves  <palves@redhat.com>

	* common/gdb_optional.h (optional::optional): Make constexpr and
	initialize m_dummy.
This commit is contained in:
Pedro Alves 2017-04-04 23:49:27 +01:00
parent f3b8f8ee35
commit c053b65441
2 changed files with 8 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2017-04-05 Pedro Alves <palves@redhat.com>
* common/gdb_optional.h (optional::optional): Make constexpr and
initialize m_dummy.
2017-04-04 John Baldwin <jhb@FreeBSD.org>
* amd64-fbsd-tdep.c: Remove "bsd-uthread.h" include.

View File

@ -34,8 +34,9 @@ class optional
{
public:
optional ()
: m_instantiated (false)
constexpr optional ()
: m_dummy (),
m_instantiated (false)
{
}