https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Paul Fee <paul.f.fee at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |paul.f.fee at gmail dot com

--- Comment #65 from Paul Fee <paul.f.fee at gmail dot com> ---
Below is some code that produces unexpected -Wmaybe-uninitialized warnings.  Is
this a variant of this bug or a separate bug?

I've tried a few configurations:

Unexpected warnings:
$ g++-10 -Wall -O2 warn.cpp -DBOOST
warn.cpp: In function ‘int main()’:
warn.cpp:19:10: warning: ‘*((void*)& i +1)’ may be used uninitialized in this
function [-Wmaybe-uninitialized]
   19 |     m_i(i)
      |          ^
warn.cpp:32:10: note: ‘*((void*)& i +1)’ was declared here
   32 |     optb i;
      |          ^

No warnings (c++17 flag not needed with GCC 11).
$ g++-10 -Wall -O2 warn.cpp -std=c++17 
$ g++-11 -Wall -O2 warn.cpp -DBOOST
$ g++-11 -Wall -O2 warn.cpp 

The constructor takes three optional<std::string> and one optional<bool>. 
Adjusting the number and types of parameters makes a difference, but I don't
see why.  Perhaps with less parameters, passing by register rather than stack
memory affects warning generation.  However 4 x optional<std::string> gives no
warning and that would be larger than 3 x optional<std::string> plus 1 x
optional<bool>.

It's not clear why std::optional would be free from warnings, yet
boost::optional not.  Is adoption of std::optional an effective way of avoiding
unnecessary -Wmaybe-uninitialized warnings?

It seems that GCC 11 has better behaviour.  Is this expected or would some
other (perhaps larger) collection of parameters trigger the same warning with
GCC 11?

If GCC 11 incorporates a specific fix, will that be backported to GCC 10?

Tested with GCC on openSUSE Tumbleweed.  Package versions:
gcc10-c++-10.3.0+git1587-2.1.x86_64
gcc11-c++-11.1.1+git340-1.1.x86_64

The source for warn.cpp:
========================
#include <string>

#ifdef BOOST
#include <boost/optional.hpp>
using opts = boost::optional<std::string>;
using optb = boost::optional<bool>;
#else
#include <optional>
using opts = std::optional<std::string>;
using optb = std::optional<bool>;
#endif

class foo
{
public:
    foo(opts a, opts b, opts c,
        optb i)
    : m_a(a), m_b(b), m_c(c),
      m_i(i)
    {}

private:
    opts m_a;
    opts m_b;
    opts m_c;
    optb m_i;
};

int main()
{
    opts a, b, c;
    optb i;

    foo bar(a, b, c, i);
}

Reply via email to