https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94970
--- Comment #2 from Iain Buclaw <ibuclaw at gdcproject dot org> --- Because RegexMatch needs destruction, a temporary is created that requires scope destruction. The temporary is wrapped in a TARGET_EXPR, and dtor call set in TARGET_EXPR_CLEANUP. TARGET_EXPR <D.4046, tmp = m () [return slot optimization], __dtor(&tmp)> A clean-up point is then created around the initialization of 'a'. <<cleanup_point a = ... >> The problem is that for the array concat expression on the RHS, a BIND_EXPR is set-up for a temporary created for the character literal (its address needs to be taken). The routine gimplify_cleanup_point_expr does not look any lower than the first level of sequences in the body, so it completely misses the GIMPLE_WITH_CLEANUP_EXPRs in the following: { const char D.4043; try { D.4043 = 32; D.4110.length = 1; D.4110.ptr = &D.4043; __tmpfordtor57 = m (); [return slot optimization] <<< Unknown GIMPLE statement: gimple_with_cleanup_expr >>> <<< Unknown GIMPLE statement: gimple_with_cleanup_expr >>> D.4111 = index (&__tmpfordtor57); D.4112 = _d_arraycatT (&_D12TypeInfo_Aya6__initZ, D.4111, D.4110); retval.0 = VIEW_CONVERT_EXPR<struct >(D.4112); } finally { D.4043 = {CLOBBER}; } } retval.1 = retval.0; a = retval.1; There is a note above gimplify_cleanup_point_expr: FIXME should we complexify the prequeue handling instead? Or use flags for all the cleanups and let the optimizer tighten them up? The current code seems pretty fragile; it will break on a cleanup within any non-conditional nesting. But any such nesting would be broken, anyway; we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct and continues out of it. We can do that at the RTL level, though, so having an optimizer to tighten up try/finally regions would be a Good Thing.