From 9032ee670f378268a3c53dee43ccaa962dfd3ecc Mon Sep 17 00:00:00 2001 From: "ngeoffray@google.com" Date: Wed, 6 Mar 2013 08:41:41 +0000 Subject: [PATCH] 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 --- .../compiler/implementation/ssa/optimize.dart | 3 ++- .../compiler/implementation/ssa/types.dart | 10 +++++++--- tests/corelib/corelib.status | 3 --- tests/language/type_intersection_test.dart | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 tests/language/type_intersection_test.dart diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart index a9c1983d3a7..ad89572fceb 100644 --- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart +++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart @@ -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); diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart index ec73cb0e10a..f24f863b476 100644 --- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart +++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart @@ -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; } } diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status index 089101bdfb9..28cc8f8fb4c 100644 --- a/tests/corelib/corelib.status +++ b/tests/corelib/corelib.status @@ -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. diff --git a/tests/language/type_intersection_test.dart b/tests/language/type_intersection_test.dart new file mode 100644 index 00000000000..a6e260372cf --- /dev/null +++ b/tests/language/type_intersection_test.dart @@ -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)); +}