Files
sdk/pkg/compiler/test/codegen/gvn_test.dart
T
Stephen Adams 45efccb5e0 Remove left-over patch declarations for List constructor.
This CL replaces https://dart-review.googlesource.com/c/sdk/+/296900

The `List` constructor is removed in Dart 3.0.
Some of the `@patch` implementations were not removed.

This is *high priority*. It seems the left-over `@patch factory List` constructor did not cause any errors, instead it *added* a constructor  to `List` that can be used in web compiled code. Even if `List` doesn't have such a constructor in the SDK code proper.
The VM and analyzer will say the invocation is an error, but dart2js happily compiles it and runs.

(It used to be that patches couldn't add public members, that security seems to have been removed.)

Also removes code which tries to detect "the unnamed List constructor",
which is no longer a thing, and a number of invocations of the constructor, where it's not clear that the test is aware that the constructor no longer exists, and is not marked as `@dart=2.x` with x < 12.

TEST=ci

Change-Id: I4ffaf3ae2c4e75ca06e7ba0bf19187b6376f3888
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/297100
Reviewed-by: Brian Quinlan <bquinlan@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
2023-04-22 00:38:28 +00:00

145 lines
3.4 KiB
Dart

// Copyright (c) 2011, 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.
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import '../helpers/compiler_helper.dart';
const String TEST_ONE = r"""
void foo(bar) {
for (int i = 0; i < 1; i++) {
print(1 + bar);
print(1 + bar);
}
}
""";
// Check that modulo does not have any side effect and we are
// GVN'ing the length of [:list:].
const String TEST_TWO = r"""
void foo(a) {
var list = <int>[];
list[0] = list[0 % a];
list[1] = list[1 % a];
}
""";
// Check that is checks get GVN'ed.
const String TEST_THREE = r"""
void foo(a) {
print(42); // Make sure numbers are used.
print(a is num);
print(a is num);
}
""";
// Check that instructions that don't have a builtin equivalent can
// still be GVN'ed.
const String TEST_FOUR = r"""
void foo(a) {
print(1 >> a);
print(1 >> a);
}
""";
// Check that [HCheck] instructions do not prevent GVN.
const String TEST_FIVE = r"""
class A {
final int foo;
A(this.foo);
}
class B {}
main() {
helper([new A(32), A(21), B(), null][0]);
}
helper(A a) {
var b = a.foo;
var c = a.foo;
if (a is B) {
c = (a as dynamic).foo;
}
return b + c;
}
""";
// Check that a gvn'able instruction in the loop header gets hoisted.
const String TEST_SIX = r"""
class A {
@pragma('dart2js:noElision')
final field = 54;
}
main() {
dynamic a = A();
while (a.field == 54) { a.field = 42; }
}
""";
// Check that a gvn'able instruction that may throw in the loop header
// gets hoisted.
const String TEST_SEVEN = r"""
class A {
final field;
A() : field = null;
A.bar() : field = 42;
}
main() {
dynamic a = A();
dynamic b = A.bar();
while (a.field == 54) { a.field = 42; b.field = 42; }
}
""";
// Check that a check in a loop header gets hoisted.
const String TEST_EIGHT = r"""
class A {
final field;
A() : field = null;
A.bar() : field = 42;
}
main() {
dynamic a = A();
dynamic b = A.bar();
for (int i = 0; i < a.field; i++) { a.field = 42; b.field = 42; }
}
""";
main() {
asyncTest(() async {
await compile(TEST_ONE, entry: 'foo', check: (String generated) {
RegExp regexp = RegExp(r"1 \+ [a-z]+");
checkNumberOfMatches(regexp.allMatches(generated).iterator, 1);
});
await compile(TEST_TWO, entry: 'foo', check: (String generated) {
checkNumberOfMatches(RegExp("length").allMatches(generated).iterator, 1);
});
await compile(TEST_THREE, entry: 'foo', check: (String generated) {
checkNumberOfMatches(RegExp("number").allMatches(generated).iterator, 1);
});
await compile(TEST_FOUR, entry: 'foo', check: (String generated) {
checkNumberOfMatches(RegExp("shr").allMatches(generated).iterator, 1);
});
await compileAll(TEST_FIVE).then((generated) {
checkNumberOfMatches(RegExp(r"\.foo;").allMatches(generated).iterator, 1);
checkNumberOfMatches(
RegExp(r"get\$foo\(").allMatches(generated).iterator, 0);
});
await compileAll(TEST_SIX).then((generated) {
Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)'));
});
await compileAll(TEST_SEVEN).then((generated) {
Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)'));
});
await compileAll(TEST_EIGHT).then((generated) {
Expect.isTrue(generated.contains('for (; i < t1; ++i)'));
});
});
}