Don't store references to unreachable `FunctionExitNodes`
Currently, every FunctionEntryNode
has a corresponding FunctionExitNode
. This is fine for programs where every function may return normally, but problematic for programs that contain non-returning functions (i.e., functions that do not return by executing a return statement or by reaching the end of the function body). Common causes for non-returning functions are infinite loops (e.g., ERROR:; goto ERROR;
) and functions that lead to program termination (e.g., abort()
, exit(int)
). FunctionExitNodes
of non-returning functions are not reachable, don't have incident edges and are not even part of a CFA (they are not in the collection returned by CFA#getAllNodes()
). This makes dealing with FunctionExitNodes
more difficult that it should be and can be confusing at first, because the documentation does not mention this special case.
The concrete proposal is to make FunctionEntryNode#getExitNode()
return Optional<FunctionExitNode>
and only store references to FunctionExitNodes
that are reachable and part of a CFA. Even though FunctionEntryNode#getExitNode()
is used moderately often, most necessary changes seem to be quite straight forward.