blob: 21f926307ffc5e9a038f07bc1768308b002bbb89 [file] [log] [blame]
// Copyright (c) 2020, 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.
// These tests verify that the kinds of constructs we expect to cause type
// promotion continue to function properly even when used inside unreachable
// code.
abstract class C {
void f(Object x, Object y);
}
andExpression_alwaysFalse(Object o) {
return;
o is! int && (throw 'x');
/*int*/ o;
}
andExpression_alwaysTrue(Object o) {
return;
true && (o is int || (throw 'x'));
/*int*/ o;
}
andExpression_lhsAlwaysTrue(Object o) {
return;
if (true && o is! int) {
o;
} else {
/*int*/ o;
}
}
andExpression_rhsAlwaysTrue(Object o) {
return;
if (o is! int && true) {
o;
} else {
/*int*/ 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';
/*int*/ o;
}
conditionalIsNot(Object o) {
return;
o is! int ? throw 'bad' : null;
/*int*/ o;
}
conditionalJoinFalse(Object o, bool b) {
return;
if (b ? o is! int : o is! int) return;
/*int*/ o;
}
conditionalJoinTrue(Object o, bool b) {
return;
if (!(b ? o is int : o is int)) return;
/*int*/ o;
}
doBreak(Object o) {
return;
do {
if (o is int) break;
} while (true);
/*int*/ o;
}
doContinue(Object o) {
return;
do {
if (o is int) continue;
return;
} while (false);
/*int*/ o;
}
doCondition(Object o) {
return;
do {} while (o is! int);
/*int*/ o;
}
forBreak(Object o) {
return;
for (;;) {
if (o is int) break;
}
/*int*/ o;
}
forContinue(Object o) {
return;
for (;; /*int*/ o) {
if (o is int) continue;
return;
}
}
ifIsNot(Object o) {
return;
if (o is! int) return;
/*int*/ o;
}
ifIsNot_listElement(Object o) {
return;
[if (o is! int) throw 'x'];
/*int*/ o;
}
ifIsNot_setElement(Object o) {
return;
({if (o is! int) throw 'x'});
/*int*/ o;
}
ifIsNot_mapElement(Object o) {
return;
({if (o is! int) 0: throw 'x'});
/*int*/ o;
}
ifNull(Object o, Object? p, Object q, void Function(Object, Object) f) {
return;
(o is int ? p : throw 'x') ?? f(o = q, throw 'x');
/*int*/ o;
}
labeledStatement(Object o) {
return;
label:
{
if (o is int) break label;
return;
}
/*int*/ o;
}
nullAwareAccess(Object o, C? p, Object q) {
return;
(o is int ? p : throw 'x')?.f(o = q, throw 'x');
/*int*/ o;
}
orExpression_alwaysFalse(Object o) {
return;
false || (o is! int && (throw 'x'));
/*int*/ o;
}
orExpression_alwaysTrue(Object o) {
return;
o is int || (throw 'x');
/*int*/ o;
}
orExpression_lhsAlwaysFalse(Object o) {
return;
if (false || o is int) {
/*int*/ o;
} else {
o;
}
}
orExpression_rhsAlwaysFalse(Object o) {
return;
if (o is int || false) {
/*int*/ o;
} else {
o;
}
}
switchPromoteInCase(Object o, int i) {
return;
switch (i) {
case 0:
if (o is! int) return;
break;
default:
return;
}
/*int*/ o;
}
switchPromoteInImplicitDefault(Object o, int i, Object p) {
return;
if (o is! int) return;
switch (i) {
case 0:
o = p;
return;
}
/*int*/ o;
}
tryCatchPromoteInTry(Object o) {
return;
try {
if (o is! int) return;
} catch (_) {
return;
}
/*int*/ o;
}
tryCatchPromoteInCatch(Object o) {
return;
try {
return;
} catch (_) {
if (o is! int) return;
}
/*int*/ o;
}
whileBreak(Object o) {
return;
while (true) {
if (o is int) break;
}
/*int*/ o;
}