> > if (!single_succ_p (bb)) > > - return; > > + { > > + int num_eh, num_other; > > + bb_get_succ_edge_count (bb, num_eh, num_other); > > + /* Allow EH edges so that we can give a better > > + error message later. */ > > Please instead use has_abnormal_or_eh_outgoing_edge_p (bb) instead
That's not equivalent, need a num_other == 1 check too. Do you want me to move the function to a generic place? > to avoid adding another function like this. Also only continue searching > for a musttail call if cfun->has_musttail Done (although I must say I liked the better dump messages even for non tailcall) > > if (gimple_references_memory_p (stmt) > > || gimple_has_volatile_ops (stmt)) > > - return; > > + { > > + bad_stmt = true; > > break here when !cfun->has_musttail? Done. > > if (ass_var > > && !is_gimple_reg (ass_var) > > && !auto_var_in_fn_p (ass_var, cfun->decl)) > > - return; > > + { > > + maybe_error_musttail (call, _("return value in memory")); > > + return; > > + } > > + > > + if (cfun->calls_setjmp) > > + { > > + maybe_error_musttail (call, _("caller uses setjmp")); > > + return; > > + } > > > > /* If the call might throw an exception that wouldn't propagate out of > > cfun, we can't transform to a tail or sibling call (82081). */ > > - if (stmt_could_throw_p (cfun, stmt) > > - && !stmt_can_throw_external (cfun, stmt)) > > + if ((stmt_could_throw_p (cfun, stmt) > > + && !stmt_can_throw_external (cfun, stmt)) || !single_succ_p (bb)) > > This reports for the found stmt while above we reject any intermediate > non-fallthru control flow. I would suggest to, in the above BB check, > record a gimple *last = last_stmt (bb) and if last == stmt report this reason > but otherwise "control altering statement between call and return"? Ok. I reported "code between call and return". I don't think there since "control" would imply control flow. Also there is no last_stmt () or did I miss it? It couldn't be used anyways because it still needs to skip the nops etc. But the backwards loop can easily discover it. BTW I suspect some of the checks are redundant but it is hard to really prove it, so I left everything in place. > > + maybe_error_musttail (call, > > + _("call may throw exception that does not > > propagate")); > > return; > > + } > > > > /* If the function returns a value, then at present, the tail call > > must return the same type of value. There is conceptually a copy > > @@ -524,7 +593,10 @@ find_tail_calls (basic_block bb, struct tailcall > > **ret, bool only_musttail) > > if (result_decl > > && may_be_aliased (result_decl) > > && ref_maybe_used_by_stmt_p (call, result_decl, false)) > > - return; > > + { > > + maybe_error_musttail (call, _("tail call must be same type")); > > ? "call uses the return slot"? > > Otherwise looks OK. Done. Although I'm not sure what a return slot is, but maybe the users can figure it out) -Andi