https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|c++ |tree-optimization Known to work| |5.5.0 Summary|std::optional and bogus |[8/9/10 regression] |-Wmaybe-uninitialized |std::optional and bogus |warning |-Wmaybe-uninitialized | |warning Known to fail| |10.0, 6.5.0, 7.3.1, 8.3.1, | |9.2.1 --- Comment #37 from Jason Merrill <jason at gcc dot gnu.org> --- Regression from GCC 5, because with the GCC 6 -flifetime-dse changes we properly recognize the initial state of the object as uninitialized; with -fno-lifetime-dse we think it starts out zero-initialized. The problem is that we have two parallel variables that aren't being treated as parallel. From the .optimized dump of the comment 0 test using std::optional (because the warning is correct for the over-reduced optional): <bb 7> [count: 0]: # maybe_a$m_51 = PHI <maybe_a$m_38(D)(2), _29(5)> // _M_value # maybe_a$4_54 = PHI <0(2), 1(5)> // _M_engaged ... _12 = VIEW_CONVERT_EXPR<bool>(maybe_a$4_54); if (_12 != 0) goto <bb 10>; [0.00%] else goto <bb 11>; [0.00%] <bb 10> [count: 0]: set (maybe_a$m_51); Here maybe_a$m_51 is uninitialized iff maybe_a$4_54 is 0, and in that case we don't use the uninitialized value. The PHIs are completely parallel. I'm a bit surprised the optimizer doesn't already handle this sort of situation, where a conditional jump determines which PHI argument we have, and therefore should be able to select the corresponding argument from parallel PHIs in the target block. So bb 10 should be set (_29); and we shouldn't get the warning.