There are four ways to enter a finally block:
- Normal termination of the try-catch code,
- Throw of an uncaught throwable,
- Return, and
- Branch (Break or Continue) to a containing statement.
The existing synthesized code keeps track of ways 3 and 4 but blithely assumes that ways 1 and 2 could always happen.
The problem reported here occurs when there is no normal termination (way 1 cannot happen). This creates an unreachable code-flow that doesn't do the right thing. (The reported code also results in an unreachable code-flow to handle uncaught exceptions, way 2. But, since this path ends in a throw, it is less problematic.)
I don't believe that inlining finally blocks for ways 3 and 4 will solve the problem. Reachability analysis is needed to deduce when normal termination is impossible.