7703609cc1
Try/finally statements have an unusual property that needs to be handled in a special way by flow analysis: within the `finally` block, the `try` block might not have run to completion, but after the try/finally statement, the `try` block is known to have run to completion. Therefore, even though the code that follows the try/finally statement is immediately preceded by the end of the `finally` block, the flow states of those two control flow points might not be the same. Flow analysis accounts for this situation by analyzing the `finally` block as though it started executing right after the beginning of the `try` block, but with all variables that are written within the `try` block demoted. Then, after it finishes analyzing the `finally` block, it builds a fresh flow model by starting with the flow state after the end of the `try` block, and then applying any promotions that were performed within the `finally` block. This is accomplished by the `FlowModel.attachFinally` method. The following changes had to be made to make this work with field promotion: - If a given promotion key appears in the "after try" model but not the "after finally" model, it might represent a field that was promoted during the `try` block, so the promotion needs to be preserved. Previously, this situation could only occur if the promotion key represented a variable declared in the `try` block (and therefore the variable would not be accessible after the try/finally statement), so the promotion could be safely dropped. - If a given promotion key appears in the "after try" model and the "after finally" model, but not the "before finally" model, it might represent a field that was promoted within both the `try` and `finally` blocks, so the promotions need to be combined. Previously, this situation could not occur, so the promotion could be safely dropped. - If a given promotion key is associated with the same SSA node in the "before finally" and "after finally" models, but a different SSA node in the "after try" model, that means that the corresponding variable was assigned in the `try` block but not in the `finally` block. If any properties of the variable were promoted within the `finally` block, those promotions were applied to the SSA nodes used by the `finally` block, and don't appear in the SSA nodes used in the "after try" model. So those promotions need to be transferred. This is accomplished by the new `SsaNode._applyPropertyPromotions` method. - If a given promotion key appears in the "after finally" model but not the "after try" model, it might represent a field that was promoted during the `finally` block, so the promotion needs to be preserved. Previously, this situation could only occur if the promotion key represented a variable declared in the `finally` block (and therefore the variable would not be accessible after the try/finally statement), so the promotion could be safely dropped. Fixes https://github.com/dart-lang/sdk/issues/53225. Bug: https://github.com/dart-lang/sdk/issues/53225 Change-Id: Ie4b635dbf838447d6964c326e1ecebfff99bed8e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320961 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Paul Berry <paulberry@google.com>