| Index: sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
|
| index e3a107b5abc90afdae0ffa1329418bcfa668b437..4122364bcf5d8679114d48b0f188adeddc22c423 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
|
| @@ -140,21 +140,37 @@ class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
|
| }
|
|
|
| HType visitTypeConversion(HTypeConversion instruction) {
|
| - HType oldType = instruction.instructionType;
|
| - // Do not change a checked mode check.
|
| - if (instruction.isCheckedModeCheck) return oldType;
|
| - // We must make sure a type conversion for receiver or argument check
|
| - // does not try to do an int check, because an int check is not enough.
|
| - // We only do an int check if the input is integer or null.
|
| - HInstruction checked = instruction.checkedInput;
|
| - if (oldType.isNumber()
|
| - && !oldType.isDouble()
|
| - && checked.isIntegerOrNull()) {
|
| - return HType.INTEGER;
|
| - } else if (oldType.isInteger() && !checked.isIntegerOrNull()) {
|
| - return HType.NUMBER;
|
| + HType inputType = instruction.checkedInput.instructionType;
|
| + HType checkedType = instruction.checkedType;
|
| + if (instruction.isArgumentTypeCheck || instruction.isReceiverTypeCheck) {
|
| + // We must make sure a type conversion for receiver or argument check
|
| + // does not try to do an int check, because an int check is not enough.
|
| + // We only do an int check if the input is integer or null.
|
| + if (checkedType.isNumber()
|
| + && !checkedType.isDouble()
|
| + && inputType.isIntegerOrNull()) {
|
| + instruction.checkedType = HType.INTEGER;
|
| + } else if (checkedType.isInteger() && !inputType.isIntegerOrNull()) {
|
| + instruction.checkedType = HType.NUMBER;
|
| + }
|
| + }
|
| +
|
| + HType outputType = checkedType.intersection(inputType, compiler);
|
| + if (outputType.isConflicting()) {
|
| + // Intersection of double and integer conflicts (is empty), but JS numbers
|
| + // can be both int and double at the same time. For example, the input
|
| + // can be a literal double '8.0' that is marked as an integer (because 'is
|
| + // int' will return 'true'). What we really need to do is make the
|
| + // overlap between int and double values explicit in the HType system.
|
| + if (inputType.isIntegerOrNull() && checkedType.isDoubleOrNull()) {
|
| + if (inputType.canBeNull() && checkedType.canBeNull()) {
|
| + outputType = HType.DOUBLE_OR_NULL;
|
| + } else {
|
| + outputType = HType.DOUBLE;
|
| + }
|
| + }
|
| }
|
| - return oldType;
|
| + return outputType;
|
| }
|
|
|
| HType visitTypeKnown(HTypeKnown instruction) {
|
|
|