https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89785
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2019-03-22 Ever confirmed|0 |1 --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The bug is then in potential_constant_expression_1: case SWITCH_STMT: if (!RECUR (SWITCH_STMT_COND (t), rval)) return false; /* FIXME we don't check SWITCH_STMT_BODY currently, because even unreachable labels would be checked. */ return true; This is not conservatively correct as the testcases show. The question is how much effort we do want to spend on that. The simplest might be to add *jump_target = integer_zero_node; before the return true; above, that will just assume any switch can return and not check both the switch body (which isn't checked even now) nor anything after the switch. Another option, slightly more involved, is say cp_walk_tree on SWITCH_STMT_BODY, looking for any RETURN_EXPRs or CONTINUE_STMTs (the latter only when not nested inside of a FOR_STMT, DO_STMT, WHILE_STMT and RANGE_FOR_STMT) and if we find a RETURN_EXPR, set jump_target to that, if we don't, but find a CONTINUE_STMT not nested in further looping constructs, set *jump_target to that CONTINUE_STMT, otherwise keep it unchanged. To me this looks like the best approach for now. Another option is try to do something for the case when SWITCH_STMT_COND is constant, but already for that we'd need to greatly extend the simplified: if (*jump_target) /* If we are jumping, ignore everything. This is simpler than the cxx_eval_constant_expression handling because we only need to be conservatively correct, and we don't necessarily have a constant value available, so we don't bother with switch tracking. */ return true; so that we do walk statements that can embed other statements like cxx_eval_constant_expression does and all of that stuff, with label_matches etc. And if the above is done, we could have some also some mode in which for non-constant SWITCH_STMT_COND we could say set *jump_target to the SWITCH_STMT itself and treat it as a walk which walks the switch body, if it finds some CASE_LABEL_EXPR, it will change it to some other mode which will start processing all the expressions; if we detect something that is not a potential constant expression, we would at the level of whole stmts switch back to that *jump_target = SWITCH_STMT mode and keep looking for another CASE_LABEL_EXPR and that way, if for any of the switch condition values there would be a potential constant expression, we'd succeed, otherwise fail, and even set jump_target properly based on that. But this would be quite a lot of work. Jason, any preferences here?