mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:41:41 +00:00
Make variables assigned in a loop not definitely unassigned anywhere in the loop.
Bug: https://github.com/dart-lang/sdk/issues/42301 Change-Id: I75962b976427cef7f40025f1dcd9f27400306825 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151047 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
28231a790b
commit
a1fc2ea80c
|
@ -1270,6 +1270,7 @@ class FlowModel<Variable, Type> {
|
|||
Iterable<Variable> writtenVariables,
|
||||
Iterable<Variable> capturedVariables) {
|
||||
Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
|
||||
|
||||
for (Variable variable in writtenVariables) {
|
||||
VariableModel<Variable, Type> info = infoFor(variable);
|
||||
if (info.promotedTypes != null) {
|
||||
|
@ -1278,6 +1279,7 @@ class FlowModel<Variable, Type> {
|
|||
variableInfo))[variable] = info.discardPromotions();
|
||||
}
|
||||
}
|
||||
|
||||
for (Variable variable in capturedVariables) {
|
||||
VariableModel<Variable, Type> info = variableInfo[variable];
|
||||
if (info == null) {
|
||||
|
@ -1291,8 +1293,14 @@ class FlowModel<Variable, Type> {
|
|||
variableInfo))[variable] = info.writeCapture();
|
||||
}
|
||||
}
|
||||
if (newVariableInfo == null) return this;
|
||||
return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
|
||||
|
||||
FlowModel<Variable, Type> result = newVariableInfo == null
|
||||
? this
|
||||
: new FlowModel<Variable, Type>._(reachable, newVariableInfo);
|
||||
|
||||
result = result.joinUnassigned(written: writtenVariables);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Updates the state to reflect a control path that is known to have
|
||||
|
@ -2433,8 +2441,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
|
|||
|
||||
@override
|
||||
void for_end() {
|
||||
FlowModel<Variable, Type> afterUpdate = _current;
|
||||
|
||||
_WhileContext<Variable, Type> context =
|
||||
_stack.removeLast() as _WhileContext<Variable, Type>;
|
||||
// Tail of the stack: falseCondition, break
|
||||
|
@ -2442,7 +2448,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
|
|||
FlowModel<Variable, Type> falseCondition = context._conditionInfo.ifFalse;
|
||||
|
||||
_current = _join(falseCondition, breakState);
|
||||
_current = _current.joinUnassigned(other: afterUpdate);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2481,9 +2486,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
|
|||
_stack.add(new _SimpleContext(_current));
|
||||
_current = _current.removePromotedAll(_assignedVariables._anywhere._written,
|
||||
_assignedVariables._anywhere._captured);
|
||||
_current = _current.joinUnassigned(
|
||||
written: _assignedVariables._anywhere._written,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2752,9 +2754,8 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
|
|||
|
||||
AssignedVariablesNodeInfo<Variable> info =
|
||||
_assignedVariables._getInfoForNode(body);
|
||||
FlowModel<Variable, Type> beforeCatch = beforeBody
|
||||
.removePromotedAll(info._written, info._captured)
|
||||
.joinUnassigned(other: afterBody);
|
||||
FlowModel<Variable, Type> beforeCatch =
|
||||
beforeBody.removePromotedAll(info._written, info._captured);
|
||||
|
||||
context._beforeCatch = beforeCatch;
|
||||
context._afterBodyAndCatches = afterBody;
|
||||
|
@ -2843,9 +2844,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
|
|||
void whileStatement_end() {
|
||||
_WhileContext<Variable, Type> context =
|
||||
_stack.removeLast() as _WhileContext<Variable, Type>;
|
||||
FlowModel<Variable, Type> afterBody = _current;
|
||||
_current = _join(context._conditionInfo.ifFalse, context._breakModel);
|
||||
_current = _current.joinUnassigned(other: afterBody);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -40,7 +40,7 @@ breakOuterFromInner(bool c) {
|
|||
condition() {
|
||||
late int v1, v2;
|
||||
do {
|
||||
/*unassigned*/ v1; // assigned in the condition, but not yet
|
||||
v1;
|
||||
} while ((v1 = 0) + (v2 = 0) >= 0);
|
||||
v2;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,56 @@
|
|||
// 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.
|
||||
|
||||
for_assignedInBody_body(bool b) {
|
||||
late int v;
|
||||
for (;;) {
|
||||
if (b) {
|
||||
v = 0;
|
||||
} else {
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
for_assignedInBody_condition() {
|
||||
bool firstTime = true;
|
||||
late int v;
|
||||
for (; firstTime || v > 0;) {
|
||||
firstTime = false;
|
||||
v = 5;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
for_assignedInBody_initializer() {
|
||||
bool firstTime = true;
|
||||
late int v;
|
||||
for (var x = /*unassigned*/ v;;) {
|
||||
v = 5;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
for_assignedInCondition() {
|
||||
bool firstTime = true;
|
||||
late int v;
|
||||
for (var x = /*unassigned*/ v; (v = 0) > 0;) {
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
for_assignedInUpdater() {
|
||||
bool firstTime = true;
|
||||
late int v;
|
||||
for (var x = /*unassigned*/ v;; v = 0) {
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
for_body(bool c) {
|
||||
late int v;
|
||||
for (; c;) {
|
||||
|
@ -77,7 +127,7 @@ for_initializer_variable() {
|
|||
for_updaters(bool c) {
|
||||
late int v1, v2, v3, v4;
|
||||
for (; c; v1 = 0, v2 = 0, v3 = 0, /*unassigned*/ v4) {
|
||||
/*unassigned*/ v1;
|
||||
v1;
|
||||
}
|
||||
v2;
|
||||
}
|
||||
|
@ -115,7 +165,7 @@ collection_for_initializer_variable() {
|
|||
|
||||
collection_for_updaters(bool c) {
|
||||
late int v1, v2, v3, v4;
|
||||
[for (; c; v1 = 0, v2 = 0, v3 = 0, /*unassigned*/ v4) /*unassigned*/ v1 ];
|
||||
[for (; c; v1 = 0, v2 = 0, v3 = 0, /*unassigned*/ v4) v1];
|
||||
v2;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ void method1() {
|
|||
local = 0;
|
||||
return;
|
||||
} finally {
|
||||
print(/*unassigned*/ local);
|
||||
print(local);
|
||||
}
|
||||
local;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ void method2() {
|
|||
local = 42;
|
||||
rethrow;
|
||||
} finally {
|
||||
print(/*unassigned*/ local);
|
||||
print(local);
|
||||
}
|
||||
local;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,29 @@
|
|||
// 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.
|
||||
|
||||
assignedInBody_body(bool b) {
|
||||
late int v;
|
||||
while (true) {
|
||||
if (b) {
|
||||
v = 0;
|
||||
} else {
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
assignedInBody_condition() {
|
||||
bool firstTime = true;
|
||||
late int v;
|
||||
while (firstTime || v > 0) {
|
||||
firstTime = false;
|
||||
v = 5;
|
||||
}
|
||||
v;
|
||||
}
|
||||
|
||||
condition() {
|
||||
late int v;
|
||||
while ((v = 0) >= 0) {
|
||||
|
|
Loading…
Reference in a new issue