[cfg] Fix handling of unreachable AST in TryCatch and field initializers

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: I189d7d3704c29b1350df23bca174990608b052ad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/467880
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
Alexander Markov
2025-12-15 07:17:46 -08:00
committed by Commit Queue
parent dee306bdf8
commit cb2b871706
3 changed files with 119 additions and 5 deletions
+15 -5
View File
@@ -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
+34
View File
@@ -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<num> unreachableFieldInitializer = [10, 1 + (throw 'Bye') + 2, 20];
void main() {}
@@ -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(<num>)
Throw(v4)