diff --git a/pkg/cfg/lib/front_end/ast_to_ir.dart b/pkg/cfg/lib/front_end/ast_to_ir.dart index 75a61e08630..eb132635106 100644 --- a/pkg/cfg/lib/front_end/ast_to_ir.dart +++ b/pkg/cfg/lib/front_end/ast_to_ir.dart @@ -94,7 +94,9 @@ class AstToIr extends ast.RecursiveVisitor { _buildImplicitSetter(member as ast.Field); case FieldInitializerFunction(): _translateNode((member as ast.Field).initializer!); - builder.addReturn(); + if (builder.hasOpenBlock) { + builder.addReturn(); + } case RegularFunction() || GetterFunction() || SetterFunction(): _translateNode(member.function?.body); case GenerativeConstructor(): @@ -900,8 +902,11 @@ class AstToIr extends ast.RecursiveVisitor { _translateNode(node.body); - final done = builder.newJoinBlock(); - builder.addGoto(done); + JoinBlock? done; + if (builder.hasOpenBlock) { + done = builder.newJoinBlock(); + builder.addGoto(done); + } builder.leaveTryBlock(); builder.startBlock(catchBlock); @@ -950,7 +955,10 @@ class AstToIr extends ast.RecursiveVisitor { _translateNode(catchClause.body); - builder.addGoto(done); + if (builder.hasOpenBlock) { + done ??= builder.newJoinBlock(); + builder.addGoto(done); + } if (next != null) { builder.startBlock(next); @@ -964,7 +972,9 @@ class AstToIr extends ast.RecursiveVisitor { builder.addRethrow(); } - builder.startBlock(done); + if (done != null) { + builder.startBlock(done); + } } @override diff --git a/pkg/cfg/testcases/unreachable_ast.dart b/pkg/cfg/testcases/unreachable_ast.dart index e9be0949688..8e62a30b3c8 100644 --- a/pkg/cfg/testcases/unreachable_ast.dart +++ b/pkg/cfg/testcases/unreachable_ast.dart @@ -57,4 +57,38 @@ void unreachableFinally() { } } +void unreachableTryEnd() { + try { + print(1); + throw 'Bye-bye'; + print(2); + } catch (_) { + print(3); + } +} + +void unreachableCatchEnd() { + try { + print(1); + } catch (_) { + print(2); + throw 'Bye-bye'; + print(3); + } +} + +void unreachableBothTryEndAndCatchEnd() { + try { + print(1); + throw 'Bye'; + print(2); + } catch (_) { + print(3); + throw 'Bye-bye'; + print(4); + } +} + +List unreachableFieldInitializer = [10, 1 + (throw 'Bye') + 2, 20]; + void main() {} diff --git a/pkg/cfg/testcases/unreachable_ast.dart.expect b/pkg/cfg/testcases/unreachable_ast.dart.expect index 64ec1feb502..c5c094e0fb9 100644 --- a/pkg/cfg/testcases/unreachable_ast.dart.expect +++ b/pkg/cfg/testcases/unreachable_ast.dart.expect @@ -97,8 +97,78 @@ B2 = CatchBlock() idom:B0 DirectCall print(v20) Throw(v22) +--- unreachableTryEnd +B0 = EntryBlock() dominates:(B2, B1) + v4 = Constant(1) + v6 = Constant("Bye-bye") + v8 = Constant(null) + v13 = Constant(3) + TryEntry(try-body: B1, catch-block: B2) +B1 = TargetBlock() exception-handler:B2 idom:B0 + DirectCall print(v4) + Throw(v6) +B2 = CatchBlock() idom:B0 + Parameter(#exception) + Parameter(#stackTrace) + DirectCall print(v13) + Return(v8) + +--- unreachableCatchEnd +B0 = EntryBlock() dominates:(B2, B1) + v4 = Constant(1) + v12 = Constant(2) + v14 = Constant("Bye-bye") + v16 = Constant(null) + TryEntry(try-body: B1, catch-block: B2) +B1 = TargetBlock() exception-handler:B2 idom:B0 + DirectCall print(v4) + Return(v16) +B2 = CatchBlock() idom:B0 + Parameter(#exception) + Parameter(#stackTrace) + DirectCall print(v12) + Throw(v14) + +--- unreachableBothTryEndAndCatchEnd +B0 = EntryBlock() dominates:(B2, B1) + v4 = Constant(1) + v6 = Constant("Bye") + Constant(null) + v13 = Constant(3) + v15 = Constant("Bye-bye") + TryEntry(try-body: B1, catch-block: B2) +B1 = TargetBlock() exception-handler:B2 idom:B0 + DirectCall print(v4) + Throw(v6) +B2 = CatchBlock() idom:B0 + Parameter(#exception) + Parameter(#stackTrace) + DirectCall print(v13) + Throw(v15) + --- main B0 = EntryBlock() v1 = Constant(null) Return(v1) +--- getter unreachableFieldInitializer +B0 = EntryBlock() + v1 = LoadStaticField(unreachableFieldInitializer) + Return(v1) + +--- setter unreachableFieldInitializer +B0 = EntryBlock() + v4 = Constant(null) + v1 = Parameter(#value) + StoreStaticField(unreachableFieldInitializer, v1) + Return(v4) + +--- field-init unreachableFieldInitializer +B0 = EntryBlock() + Constant(10) + Constant(1) + v4 = Constant("Bye") + Constant(null) + TypeArguments() + Throw(v4) +