[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field (missed CSE)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 Martin Sebor changed: What|Removed |Added CC||msebor at gcc dot gnu.org Known to fail||10.2.0, 11.0, 8.3.0, 9.3.0 Last reconfirmed|2019-01-22 00:00:00 |2021-4-6 --- Comment #7 from Martin Sebor --- The IL hasn't appreciably changed in GCC 11 so it still issues the warning, albeit with more detail. $ gcc -O2 -S -Wall pr88897.C In constructor ‘temporary_buffer::temporary_buffer(temporary_buffer&&)’, inlined from ‘optional::optional(optional&&)’ at pr88897.C:22:79, inlined from ‘void foo()’ at pr88897.C:42:57: pr88897.C:14:63: warning: ‘*(temporary_buffer*)((char*)&_local_state + offsetof(future_state, future_state::value.optional::)).temporary_buffer::_buffer’ may be used uninitialized [-Wmaybe-uninitialized] 14 | temporary_buffer(temporary_buffer &) noexcept : _buffer(x._buffer) { |~~^~~ pr88897.C: In function ‘void foo()’: pr88897.C:40:16: note: ‘_local_state’ declared here 40 | future_state _local_state; |^~~~
[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 Richard Biener changed: What|Removed |Added Keywords||missed-optimization Status|UNCONFIRMED |NEW Last reconfirmed||2019-01-22 Ever confirmed|0 |1 --- Comment #6 from Richard Biener --- So this boils down to a missed optimization (as many cases do...). The uninit warning sees [local count: 1073741825]: _3 = bar (); future_state::future_state (&_local_state); MEM[(struct &)&_local_state] ={v} {CLOBBER}; MEM[(struct optional *)&_local_state]._M_engaged = 0; MEM[(struct optional *)_3]._M_engaged = 0; _7 = MEM[(struct optional &)&_local_state]._M_engaged; if (_7 != 0) goto ; [50.00%] else goto ; [50.00%] [local count: 536870912]: _6 = MEM[(struct temporary_buffer &)&_local_state]._buffer; ... and warns about the load _6 = ... As you can see the condition isn't elided and somehow we didn't manage to CSE the load of _M_engaged here, possibly due to the appearant aliasing of the store via _3. points-to analysis explicitely says it might alias _local_state because _local_state escapes to future_state::future_state and PTA is not flow-sensitive: [local count: 1073741825]: # PT = nonlocal escaped null # USE = nonlocal null { D.2493 } (escaped) # CLB = nonlocal null { D.2493 } (escaped) _3 = bar (); # USE = nonlocal null { D.2493 } (escaped) # CLB = nonlocal null { D.2493 } (escaped) future_state::future_state (&_local_stateD.2493); MEM[(struct &)&_local_stateD.2493] ={v} {CLOBBER}; MEM[(struct optionalD.2409 *)&_local_stateD.2493]._M_engagedD.2426 = 0; MEM[(struct optionalD.2409 *)_3]._M_engagedD.2426 = 0;
[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 Rafael Avila de Espindola changed: What|Removed |Added CC||rguenther at suse dot de --- Comment #5 from Rafael Avila de Espindola --- This is a regression introduced by 4d2b9d1e3c794a05c00708035519290e920768e8.
[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 Rafael Avila de Espindola changed: What|Removed |Added Attachment #45452|0 |1 is obsolete|| Attachment #45453|0 |1 is obsolete|| --- Comment #4 from Rafael Avila de Espindola --- Created attachment 45475 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45475=edit testcase Now that I know what to look for I reduced the testcase again trying to make sure to not introduce uninitialized uses in the process. As far as I can tell the warning in the attached testcase is wrong. First an optional is constructed, but _M_engaged is false since it doesn't hold a value. It is then moved, but move constructor checks __other._M_engaged, so the temporary_buffer move constructor should never be called.
[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 --- Comment #3 from Rafael Avila de Espindola --- (In reply to Andrew Pinski from comment #2) > Some of the time, the uninitialized is due to using the object after the > lifetime of the object has gone out of scope. I have not checked if that is > the case here but I would not be suprised. Thanks! This may very well be the case. This reduces further to struct deleter { deleter(deleter &) {} deleter(deleter &) = default; }; struct temporary_buffer { temporary_buffer(temporary_buffer &) = default; char *_buffer = nullptr; deleter _deleter; }; void foo123(temporary_buffer); struct future_state { union any { any() {} temporary_buffer value; } _u; void forward_to() { foo123(_u.value); } }; void then3() { future_state _local_state; _local_state.forward_to(); } which has a real uninitialized use. I am looking again at the unreduced test case to see if that was the original issue. More context in the warning message would have been awesome! :-)
[Bug middle-end/88897] Bogus maybe-uninitialized warning on class field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88897 --- Comment #2 from Andrew Pinski --- Some of the time, the uninitialized is due to using the object after the lifetime of the object has gone out of scope. I have not checked if that is the case here but I would not be suprised.