Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 9e7dcbd1018e1dc13c38c4658be6dc6e8392012b..9ba3baf0b5c5a10f0169cf9774d79e6a91fef066 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -9293,7 +9293,16 @@ SequenceNode* Parser::EnsureFinallyClause( |
LocalVariable* rethrow_stack_trace_var) { |
TRACE_PARSER("EnsureFinallyClause"); |
ASSERT(parse || (is_async && (try_stack_ != NULL))); |
- OpenBlock(); |
+ // Increasing the loop level prevents the reuse of a parent context and forces |
+ // the allocation of a local context to hold captured variables declared |
+ // inside the finally clause. Otherwise, a captured variable gets allocated at |
+ // different slots in the parent context each time the finally clause is |
+ // reparsed, which is done to duplicate the ast. Since only one closure is |
+ // kept due to canonicalization, it will access the correct slot in only one |
+ // copy of the finally clause and the wrong slot in all others. By allocating |
+ // a local context, all copies use the same slot in different local contexts. |
+ // See issue #26948. This is a temporary fix until we eliminate reparsing. |
zra
2016/07/27 21:07:23
DBC: Probably a good idea to go ahead and file an
regis
2016/07/27 21:27:09
Done. #26975
|
+ OpenLoopBlock(); |
if (parse) { |
ExpectToken(Token::kLBRACE); |
} |