Check for canBePrimitiveNumber when doing the intersection on a number type.

Review URL: https://codereview.chromium.org//12528004

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@19536 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ngeoffray@google.com
2013-03-06 08:41:41 +00:00
parent 33a29888dd
commit 9032ee670f
4 changed files with 27 additions and 7 deletions
@@ -439,7 +439,8 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
HType leftType = left.instructionType;
HType rightType = right.instructionType;
// We don't optimize on numbers to preserve the runtime semantics.
// Intersection of int and double return conflicting, so
// we don't optimize on numbers to preserve the runtime semantics.
if (!(left.isNumberOrNull() && right.isNumberOrNull()) &&
leftType.intersection(rightType, compiler).isConflicting()) {
return graph.addConstantBool(false, constantSystem);
@@ -416,6 +416,7 @@ class HBooleanType extends HPrimitiveType {
if (other.isUnknown()) return HType.BOOLEAN;
if (other.isBooleanOrNull()) return HType.BOOLEAN;
if (other.isBoolean()) return HType.BOOLEAN;
if (other.isTop(compiler)) return HType.BOOLEAN;
return HType.CONFLICTING;
}
}
@@ -453,7 +454,7 @@ class HNumberOrNullType extends HPrimitiveOrNullType {
if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
if (other.isTop(compiler)) {
if (other.canBePrimitiveNumber(compiler)) {
return other.canBeNull() ? this : HType.NUMBER;
}
if (other.canBeNull()) return HType.NULL;
@@ -493,6 +494,7 @@ class HNumberType extends HPrimitiveType {
if (other.isIntegerOrNull()) return HType.INTEGER;
if (other.isDoubleOrNull()) return HType.DOUBLE;
if (other.isNumberOrNull()) return HType.NUMBER;
if (other.canBePrimitiveNumber(compiler)) return HType.NUMBER;
return HType.CONFLICTING;
}
}
@@ -531,7 +533,7 @@ class HIntegerOrNullType extends HNumberOrNullType {
if (other.isDoubleOrNull()) return HType.NULL;
if (other.isNumber()) return HType.INTEGER;
if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
if (other.isTop(compiler)) {
if (other.canBePrimitiveNumber(compiler)) {
return other.canBeNull() ? this : HType.INTEGER;
}
if (other.canBeNull()) return HType.NULL;
@@ -574,6 +576,7 @@ class HIntegerType extends HNumberType {
if (other.isDoubleOrNull()) return HType.CONFLICTING;
if (other.isNumber()) return HType.INTEGER;
if (other.isNumberOrNull()) return HType.INTEGER;
if (other.canBePrimitiveNumber(compiler)) return HType.INTEGER;
return HType.CONFLICTING;
}
}
@@ -612,7 +615,7 @@ class HDoubleOrNullType extends HNumberOrNullType {
if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
if (other.isNumber()) return HType.DOUBLE;
if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
if (other.isTop(compiler)) {
if (other.canBePrimitiveNumber(compiler)) {
return other.canBeNull() ? this : HType.DOUBLE;
}
if (other.canBeNull()) return HType.NULL;
@@ -655,6 +658,7 @@ class HDoubleType extends HNumberType {
if (other.isDoubleOrNull()) return HType.DOUBLE;
if (other.isNumber()) return HType.DOUBLE;
if (other.isNumberOrNull()) return HType.DOUBLE;
if (other.canBePrimitiveNumber(compiler)) return HType.DOUBLE;
return HType.CONFLICTING;
}
}
-3
View File
@@ -41,9 +41,6 @@ string_base_vm_test: Fail, OK # VM specific test.
string_replace_func_test: Skip # Bug 6554 - doesn't terminate.
[ $compiler == dart2js && $checked ]
string_codeunits_test: Fail # Issue 8904
[ $compiler == dart2js && $runtime == none ]
*: Fail, Pass # TODO(ahe): Triage these tests.
@@ -0,0 +1,18 @@
// Copyright (c) 2013, 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.
// Regression test for dart2js that used to consider that the
// intersection of [Comparable] and [num] is conflicting.
class A {
foo(a, Comparable b) => a == b;
bar(a, Comparable b) => b == a;
}
main() {
Expect.isFalse(new A().foo(1, 'foo'));
Expect.isTrue(new A().foo(1, 1));
Expect.isFalse(new A().bar(1, 'foo'));
Expect.isTrue(new A().bar(1, 1));
}