Ensure that assert statements promote properly in unreachable code.

Fixes #40009.

Bug: https://github.com/dart-lang/sdk/issues/40009
Change-Id: I96561a72b6ba8dd8b8b95a4d9827d195941ea038
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166760
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Paul Berry 2020-10-08 21:42:14 +00:00
parent 18644c338b
commit 7a1e92a670
2 changed files with 60 additions and 1 deletions

View file

@ -2729,6 +2729,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
@override
void assert_begin() {
_current = _current.split();
_stack.add(new _AssertContext<Variable, Type>(_current));
}
@ -2736,7 +2737,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
void assert_end() {
_AssertContext<Variable, Type> context =
_stack.removeLast() as _AssertContext<Variable, Type>;
_current = _join(context._previous, context._conditionInfo.ifTrue);
_current = _merge(context._previous, context._conditionInfo.ifTrue);
}
@override

View file

@ -40,6 +40,64 @@ andExpression_rhsAlwaysTrue(Object o) {
}
}
assertAlwaysThrows(Object o, Object p, bool Function(Object, Object) f) {
if (o is! int) return;
return;
assert(f(o = p, throw 'x'));
/*int*/ o;
}
class AssertAlwaysThrows_Constructor {
Object a;
Object b;
AssertAlwaysThrows_Constructor(
Object o, Object p, bool Function(Object, Object) f)
: a = o is int ? true : throw 'x',
b = throw 'x',
assert(f(o = p, throw 'x')) {
/*int*/ o;
}
}
assertFailsButMessageRepromotes(Object? o) {
if (o is! int) return;
return;
assert((o = null) != null, o is int ? 'ok' : throw 'x');
/*int*/ o;
}
class AssertFailsButMessageRepromotes_Constructor {
Object a;
Object b;
AssertFailsButMessageRepromotes_Constructor(Object? o)
: a = o is int ? true : throw 'x',
b = throw 'x',
assert((o = null) != null, o is int ? 'ok' : throw 'x') {
/*int*/ o;
}
}
assertMessageDepromotesButAlwaysThrows(Object o, Object p, bool b) {
if (o is! int) return;
return;
assert(b, throw (o = p));
/*int*/ o;
}
class AssertMessageDepromotesButAlwaysThrows {
Object a;
Object b;
AssertMessageDepromotesButAlwaysThrows(Object o, Object p, bool b)
: a = o is int ? true : throw 'x',
b = throw 'x',
assert(b, throw (o = p)) {
/*int*/ o;
}
}
conditionalIs(Object o) {
return;
o is int ? null : throw 'bad';