| Index: runtime/vm/parser.cc | 
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc | 
| index a0a0aecc68d15cfec0205f58a8ce901fdbfbeee9..8f1115eda658f365854fcc55bf620245516ad67d 100644 | 
| --- a/runtime/vm/parser.cc | 
| +++ b/runtime/vm/parser.cc | 
| @@ -6465,7 +6465,8 @@ SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { | 
| context_var, | 
| catch_clause, | 
| finally_clause, | 
| -                          try_index); | 
| +                          try_index, | 
| +                          finally_clause); | 
| current_block_->statements->Add(try_catch_node); | 
| return CloseBlock(); | 
| } | 
| @@ -6581,7 +6582,8 @@ SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 
| context_var, | 
| catch_clause, | 
| NULL,  // No finally clause. | 
| -      try_index); | 
| +      try_index, | 
| +      NULL);  // No rethrow-finally clause. | 
| current_block_->statements->Add(try_catch_node); | 
| return CloseBlock(); | 
| } | 
| @@ -8936,7 +8938,8 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 
| context_var, | 
| catch_clause, | 
| finally_clause, | 
| -                         try_index); | 
| +                         try_index, | 
| +                         finally_clause); | 
|  | 
| ASSERT(current_block_ == loop_block); | 
| loop_block->statements->Add(try_catch_node); | 
| @@ -9762,6 +9765,7 @@ AstNode* Parser::ParseTryStatement(String* label_name) { | 
| // of an existing outer try. Generate a finally clause to this purpose if it | 
| // is not declared. | 
| SequenceNode* finally_clause = NULL; | 
| +  SequenceNode* rethrow_clause = NULL; | 
| const bool parse = CurrentToken() == Token::kFINALLY; | 
| if (parse || (is_async && (try_stack_ != NULL))) { | 
| if (parse) { | 
| @@ -9795,6 +9799,21 @@ AstNode* Parser::ParseTryStatement(String* label_name) { | 
| stack_trace_var, | 
| is_async ? saved_exception_var : exception_var, | 
| is_async ? saved_stack_trace_var : stack_trace_var); | 
| +    if (finally_clause != NULL) { | 
| +      // Re-parse to create a duplicate of finally clause to avoid unintended | 
| +      // sharing of try-indices if the finally-block contains a try-catch. | 
| +      // The flow graph builder emits two copies of the finally-block if the | 
| +      // try-block has a normal exit: one for the exception- and one for the | 
| +      // non-exception case (see EffectGraphVisitor::VisitTryCatchNode) | 
| +      tokens_iterator_.SetCurrentPosition(finally_pos); | 
| +      rethrow_clause = EnsureFinallyClause( | 
| +          parse, | 
| +          is_async, | 
| +          exception_var, | 
| +          stack_trace_var, | 
| +          is_async ? saved_exception_var : exception_var, | 
| +          is_async ? saved_stack_trace_var : stack_trace_var); | 
| +    } | 
| } | 
|  | 
| CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 
| @@ -9814,7 +9833,8 @@ AstNode* Parser::ParseTryStatement(String* label_name) { | 
| // on the try/catch, close the block that's embedding the try statement | 
| // and attach the label to it. | 
| AstNode* try_catch_node = new(Z) TryCatchNode( | 
| -      try_pos, try_block, context_var, catch_clause, finally_clause, try_index); | 
| +      try_pos, try_block, context_var, catch_clause, finally_clause, try_index, | 
| +      rethrow_clause); | 
|  | 
| if (try_label != NULL) { | 
| current_block_->statements->Add(try_catch_node); | 
|  |