Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(751)

Unified Diff: pkg/compiler/lib/src/inferrer/inferrer_visitor.dart

Issue 1439603002: Fix a bug in type inference for locals in switch statements. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/compiler/dart2js/type_inference_switch_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index ab2f50c5ac1901392cb070919a5aa7f23ee46e4f..4f76443b56af3686a7151a0802127108319457fa 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -606,25 +606,33 @@ class LocalsHandler<T> {
void mergeAfterBreaks(List<LocalsHandler<T>> handlers,
{bool keepOwnLocals: true}) {
Node level = locals.block;
+ // Use a separate locals handler to perform the merge in, so that Phi
+ // creation does not invalidate previous type knowledge while we might
+ // still look it up.
+ LocalsHandler merged = new LocalsHandler.from(this, level);
Set<Local> seenLocals = new Setlet<Local>();
- // If we want to keep the locals, we first merge [this] into itself to
- // create the required Phi nodes.
- if (keepOwnLocals && !seenReturnOrThrow) {
- mergeHandler(this, seenLocals);
- }
- bool allBranchesAbort = true;
+ bool allBranchesAbort = true;
Kevin Millikin (Google) 2015/11/11 12:14:52 An extra space has crept in.
herhut 2015/12/10 10:09:11 Done.
// Merge all other handlers.
for (LocalsHandler handler in handlers) {
allBranchesAbort = allBranchesAbort && handler.seenReturnOrThrow;
- mergeHandler(handler, seenLocals);
+ merged.mergeHandler(handler, seenLocals);
}
- // Clean up Phi nodes with single input.
- locals.forEachLocal((Local variable, T type) {
- if (!seenLocals.contains(variable)) return;
- T newType = types.simplifyPhi(level, variable, type);
- if (newType != type) {
- locals[variable] = newType;
+ // If we want to keep own locals, we merge [seenLocals] from [this] into
+ // [merged] to update the Phi nodes with original values.
+ if (keepOwnLocals && !seenReturnOrThrow) {
+ for (Local variable in seenLocals) {
+ T originalType = locals[variable];
+ if (originalType != null) {
+ merged.locals[variable] = types.addPhiInput(variable,
+ merged.locals[variable],
+ originalType);
+ }
}
+ }
+ // Clean up Phi nodes with single input and store back result into
+ // actual locals handler.
+ merged.locals.forEachOwnLocal((Local variable, T type) {
+ locals[variable] = types.simplifyPhi(level, variable, type);
});
seenReturnOrThrow = allBranchesAbort &&
(!keepOwnLocals || seenReturnOrThrow);
« no previous file with comments | « no previous file | tests/compiler/dart2js/type_inference_switch_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698