https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89003
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code Known to fail| |8.2.1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed. _2 = __cxa_guard_acquire (&_ZGVZ1fvE1i); retval.1 = _2 != 0; if (retval.1 != 0) goto <D.2375>; else goto <D.2376>; <D.2375>: D.2370 = 0; try { return; i = 42; D.2370 = 1; __cxa_guard_release (&_ZGVZ1fvE1i); } catch { if (D.2370 != 0) goto <D.2377>; else goto <D.2378>; <D.2377>: goto <D.2379>; <D.2378>: __cxa_guard_abort (&_ZGVZ1fvE1i); <D.2379>: } Docs for statement expressions say "Jumping out of a statement expression is permitted, but if the statement expression is part of a larger expression then it is unspecified which other subexpressions of that expression have been evaluated except where the language definition requires certain subexpressions to be evaluated before or after the statement expression." so I'd say it behaves as documented since the statement expression is part of an initialization expression which involves locking (though not sure if that part is mandated by the standard and thus this implementation detail shouldn't trigger the unspecified behavior).