Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index eb3bd3d1a1a859ad017b5207326ff41c71220a5e..e34afd3665dbe26e94c1b1c4ae645fc756ffd34a 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -10566,6 +10566,25 @@ AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
} |
} |
} |
+ if (binary_op == Token::kIFNULL) { |
+ // Handle a ?? b. |
+ LetNode* result = new(Z) LetNode(op_pos); |
+ LocalVariable* left_temp = result->AddInitializer(lhs); |
+ const intptr_t no_pos = Scanner::kNoSourcePos; |
+ LiteralNode* null_operand = |
+ new(Z) LiteralNode(no_pos, Instance::ZoneHandle(Z)); |
+ LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
+ ComparisonNode* null_compare = |
+ new(Z) ComparisonNode(no_pos, |
+ Token::kNE_STRICT, |
+ load_left_temp, |
+ null_operand); |
+ result->AddNode(new(Z) ConditionalExprNode(op_pos, |
+ null_compare, |
+ load_left_temp, |
+ rhs)); |
+ return result; |
+ } |
return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
} |
@@ -10737,10 +10756,10 @@ AstNode* Parser::CreateAssignmentNode(AstNode* original, |
ifnull->right(), |
left_ident, |
left_pos); |
- result = new(Z) BinaryOpNode(rhs->token_pos(), |
- Token::kIFNULL, |
- ifnull->left(), |
- modified_assign); |
+ result = OptimizeBinaryOpNode(ifnull->token_pos(), |
+ ifnull->kind(), |
+ ifnull->left(), |
+ modified_assign); |
} |
return result; |
} |