Opened 6 years ago

Last modified 6 years ago

#12513 new Bugs

Boost optional (1.60/1.61/1.62) generates "may be used uninitialized" warnings with gcc 6

Reported by: romain.geissler@… Owned by: Fernando Cacciola
Milestone: To Be Determined Component: optional
Version: Boost 1.60.0 Severity: Problem
Keywords: optional gcc warning uninitialized Cc:

Description

Hi,

I have met a small case where boost::optional wrongly generates gcc warnings about maybe uninitialized values. I could reduce my case and provide the attached reproducer.

Note that this warning only happens when optimization are used (-O1 or -O2 while strangely no warning is emitted with -O3).

It's built with (from a Fedora rawhide Docker container just cloned): [root@a064b4c04fc9 tmp]# g++ -std=gnu++14 -O2 -Wall -c -o test.o test.cpp test.cpp: In function 'void someFunction(const void*)': test.cpp:22:16: warning: '*((void*)& aOptional +4)' may be used uninitialized in this function [-Wmaybe-uninitialized]

Optional_t aOptional;

[root@a064b4c04fc9 tmp]# g++ --version g++ (GCC) 6.2.1 20160916 (Red Hat 6.2.1-2) Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Other bug reports in Boost are always mentioning https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679 as the root cause, but this is not true anymore since this gcc bug was closed last year and all commits made at the time have been released in gcc 6. Please note that I could reproduce as well with the latest trunk from gcc 7.

This was reproduced with both Boost 1.60 and 1.61, but should happen as well in Boost 1.62 given that boost::optional did almost not change.

Also note that using std::experiment::optional from gcc's libstdc++ implementation works just fine.

I am not sure whether this is actually a Boost bug or a gcc one. If it's a gcc one then it's seems to be different from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679.

Can you please have a look.

Thanks, Romain

Attachments (1)

test.cpp (544 bytes ) - added by romain.geissler@… 6 years ago.
test.cpp

Download all attachments as: .zip

Change History (7)

by romain.geissler@…, 6 years ago

Attachment: test.cpp added

test.cpp

comment:1 by akrzemi1, 6 years ago

I changed your example, so that it compiles. I tested it with G++ 6.2, -std=gnu++14 -Wall -Wextra -O2, and it compiles without any warning:

http://melpon.org/wandbox/permlink/lLRX9m54qfF9jt8D

Can you confirm?

comment:2 by anonymous, 6 years ago

Hi,

What you did is simply inline what "useA" and "getAnOptional" do, in which case gcc doesn't propagate inline code the same way and doesn't reach the same conclusion about maybe uninitialized warnings. While that would be OK for some project, the way we work in my company inlining code may cause us more trouble since it would require rebuilding many libraries that we currently can't afford to rebuild each time we change the code.

It appears clear now that it is a gcc bug. Maybe we should try if adding GCC specific pragmas directly in boost to try to silence them. Currently I am using pragma in my own proprietary code to silence it, but it would be better if it would be possible in boost.

Unfortunately gcc 6.3 and the current gcc 7 trunk is still bogus...

Anyway, since it's a gcc bug, we might just close this boost issue if work it around in Boost is too complex.

Cheers, Romain

comment:3 by akrzemi1, 6 years ago

Romain, I can see that you have created a GCC bug report for this quite a while ago: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78044 From the discussion therein, I can see that -Wmaybe-uninitialized is by its nature prone to false positives.

Also, there might be no place to put the #pragmas, because the warning is reported for the inlined, optimized code.

Also, before we close this, can you check if the workaround described here http://www.boost.org/doc/libs/1_63_0/libs/optional/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html

silences the warnings for you?

comment:4 by romain.geissler@…, 6 years ago

Back then I already tried many different ways to rewrite my own code to silence the warning, including what is documented in Boost, but none of them worked. Thus I had to rely in using pragmas in my code.

The only attempt to "fix" this on Boost I found so far is the pull request a sent you a while ago, but as you, I don't like the fact that it comes at the cost of performances. I had little time to try to find another solution since then.

In 2017 I plan to move the code base of my company to C++17 and use std::optional rather than boost::optional (which does not have the issue).

If I am the only one complaining about that, I think this ticket can be closed.

comment:5 by akrzemi1, 6 years ago

You are not. This has came back many a time. I think I know how to fix that, but I am really short of time. This problem occurs only for boost::optional instantiated with scalar types (right?) The plan is to provide a specialization for trivial types that would render a trivially-copyable optional.

comment:6 by akrzemi1, 6 years ago

Ok, I reproduced your warning: http://melpon.org/wandbox/permlink/HKubpdDe7A52Ouql

But I note that the warning disappears, when I apply the workaround from the docs:

http://melpon.org/wandbox/permlink/M73b1cqYt5g9qC8E

Note: See TracTickets for help on using tickets.