https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86769
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I think what the function does is problematic for other reasons, both for WHILE_STMT and FOR_STMT. E.g. struct A { A (int); ~A (); operator bool (); }; void foo (int x) { for (int i = 0; i < 32; ++i) for (int j = 0; A a = ({ if (x == 42) continue; j < 32; }); ++j) ; } void bar (int x) { for (int i = 0; i < 32; ++i) for (int j = 0; ({ if (x == 42) continue; j < 32; }); ++j) ; } The continue should be to the outer loop, not inner, and that is how it works in bar, but not in foo. So, I'm afraid instead of doing the simplify_loop_decl_cond transformations we should just remember the preparation statements of the FOR_COND somewhere and keep FOR_COND and FOR_EXPR as separate trees until the C genericization. Though, the preparation statements include here a CLEANUP_STMT in whose first argument the body should start, so the c-family code would need to know emit actual FOR_COND + FOR_BODY + continue label (if needed) + FOR_EXPR into this subtree of the for cond preparation statement. Or another possibility would be to do the break/continue lowering in that case in the FE as well, but that isn't very clean either given that gotos aren't valid in constant expressions.