{:call, from} clauses that return without answering the caller.
A gen_statem answers a call with a {:reply, from, value} action, by
postponing the event, or by keeping from in its data to reply later.
A clause that does none of those and returns :keep_state_and_data (or
a state tuple without actions) leaves the caller blocked — for the
default :infinity of :gen_statem.call/2, forever. Finch's HTTP/2
pool did exactly that for a cancel while disconnected (sneako/finch#213).
Reading the bytecode
The event type is {x, 0}; a call clause's head tests
is_tagged_tuple {x,0} 2 :call. From the success edge of that test the
walk follows every path to a return, path-sensitively: it carries
whether the path has replied (a :reply action built, :postpone
named, :gen_statem.reply/2 called) and whether from — read with
get_tuple_element {x,0} 1 — has been handed to anything else (put
into a map, tuple or list, passed to a call), which counts as kept. A
test on {x,0} other than the call tag is another event type's clause
and ends the path. A return of the bare atom :keep_state_and_data, or
of a {:keep_state, data} / {:next_state, state, data} /
{:repeat_state, data} tuple with no actions element, on a path that
neither replied nor kept from, is an unreplied call.
Summary
Functions
Instruction indexes of returns that leave a call unanswered.
Functions
@spec analyse(Argus.Cfg.Function.t() | nil, [tuple()]) :: [non_neg_integer()]
Instruction indexes of returns that leave a call unanswered.