mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
[dart2js] Create child LocalState for inference of labeled statements.
This is analogous to what we do for other control flow constructs. Without this, a `break` to the label causes the outer scope to also appear aborted. Fixes: #48317 Bug: https://github.com/flutter/flutter/issues/96394 Change-Id: I575a5bf96b25b49df6f15d429881e310b3b34d15 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/233446 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
parent
30195a437b
commit
d539c43372
5 changed files with 76 additions and 4 deletions
|
@ -543,10 +543,13 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation>
|
|||
// Loops and switches handle their own labels.
|
||||
visit(body);
|
||||
} else {
|
||||
LocalState stateBefore = _state;
|
||||
JumpTarget jumpTarget = _localsMap.getJumpTargetForLabel(node);
|
||||
_setupBreaksAndContinues(jumpTarget);
|
||||
_state = LocalState.childPath(stateBefore);
|
||||
visit(body);
|
||||
_state.mergeAfterBreaks(_inferrer, _getBreaks(jumpTarget));
|
||||
_state = stateBefore.mergeAfterBreaks(_inferrer, _getBreaks(jumpTarget),
|
||||
keepOwnLocals: false);
|
||||
_clearBreaksAndContinues(jumpTarget);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -12,6 +12,8 @@ main() {
|
|||
noContinueInWhile();
|
||||
breakInIf();
|
||||
noBreakInIf();
|
||||
breakInBlock();
|
||||
noBreakInBlock();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -107,7 +109,7 @@ noContinueInWhile() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// A break statement in a labeled statement.
|
||||
// A conditional break statement in a labeled statement.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*member: _breakInIf:Union([exact=JSString], [exact=JSUInt31])*/
|
||||
|
@ -150,3 +152,34 @@ noBreakInIf() {
|
|||
_noBreakInIf(true);
|
||||
_noBreakInIf(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// An unconditional break statement in a labeled statement.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*member: breakInBlock:Value([exact=JSString], value: "")*/
|
||||
breakInBlock() {
|
||||
dynamic local = 42;
|
||||
label:
|
||||
{
|
||||
local = '';
|
||||
break label;
|
||||
local = false;
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The "labeled statement" above _without_ the break statement.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*member: noBreakInBlock:Value([exact=JSBool], value: false)*/
|
||||
noBreakInBlock() {
|
||||
dynamic local = 42;
|
||||
label:
|
||||
{
|
||||
local = '';
|
||||
local = false;
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
|
|
@ -560,13 +560,13 @@ testDoWhile2() {
|
|||
return a;
|
||||
}
|
||||
|
||||
/*member: testDoWhile3:[exact=JSUInt31]*/
|
||||
/*member: testDoWhile3:Value([exact=JSBool], value: false)*/
|
||||
testDoWhile3() {
|
||||
dynamic a = 42;
|
||||
do {
|
||||
a = 'foo';
|
||||
if (true) continue;
|
||||
return 42;
|
||||
return false;
|
||||
} while (true);
|
||||
// ignore: dead_code
|
||||
return a;
|
||||
|
|
18
tests/web/regress/48317_test.dart
Normal file
18
tests/web/regress/48317_test.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
helper(num c) => c * -1;
|
||||
|
||||
void main() {
|
||||
num a = 3;
|
||||
|
||||
label:
|
||||
{
|
||||
break label;
|
||||
}
|
||||
|
||||
Expect.equals(-3, helper(a));
|
||||
}
|
18
tests/web_2/regress/48317_test.dart
Normal file
18
tests/web_2/regress/48317_test.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
helper(num c) => c * -1;
|
||||
|
||||
void main() {
|
||||
num a = 3;
|
||||
|
||||
label:
|
||||
{
|
||||
break label;
|
||||
}
|
||||
|
||||
Expect.equals(-3, helper(a));
|
||||
}
|
Loading…
Reference in a new issue