[dart/vm] GenericCheckBound (AOT) may throw
Rationale:
Previous CL inadvertently removed the may-throw tag
from the AOT version of check bound. But, unlike its
speculative counterpart, this non-speculative check
will throw when out of bounds. Optimizations like LICM
rely on this property for correctness. Found with fuzzing!
https://github.com/dart-lang/sdk/issues/36803
Change-Id: I05952f423ffa1917a08dbb6191d0d1533450bc9c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100921
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Aart Bik <ajcbik@google.com>
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index d288500..b84c721 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -7543,6 +7543,8 @@
bool IsRedundant(const RangeBoundary& length);
+ virtual bool MayThrow() const { return true; }
+
private:
DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr);
};
diff --git a/tests/language_2/vm/regress_36803_test.dart b/tests/language_2/vm/regress_36803_test.dart
new file mode 100755
index 0000000..62ca189
--- /dev/null
+++ b/tests/language_2/vm/regress_36803_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, 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.
+
+// Don't LICM AOT's generic bounds check reference beyond other exception.
+// (dartbug.com/36803).
+//
+// VMOptions=--deterministic --optimization_level=3 --enable-inlining-annotations
+
+import "package:expect/expect.dart";
+
+const String NeverInline = 'NeverInline';
+
+String var1 = 'Hdi\u{1f600}T';
+
+@NeverInline
+int foo() {
+ List<int> a = [1, 2, 3, 4];
+ int x = 0;
+ do {
+ Uri.decodeQueryComponent(var1);
+ x = x + a[1000];
+ } while (x < 1);
+ return x;
+}
+
+main() {
+ int x = 0;
+ try {
+ x = foo();
+ } on RangeError catch (e) {
+ x = -2;
+ } on ArgumentError catch (e) {
+ x = -1;
+ }
+ Expect.equals(-1, x);
+}