[vm/compiler] Fixed bug with clamping on 32-bit arch Rationale: Feel the power of value-guided fuzzing that, in combination with new types, founds this issue in the graph intrinsifier. The deopt on the speculative code for Smi was missing. https://github.com/dart-lang/sdk/issues/37868 Change-Id: I9f310f62eb6cf1cdb3e39685caed5b7792024565 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/113203 Reviewed-by: Ben Konyi <bkonyi@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc index db4e7dc..d251b3e 100644 --- a/runtime/vm/compiler/graph_intrinsifier.cc +++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -285,6 +285,8 @@ case kTypedDataUint16ArrayCid: case kExternalTypedDataUint8ArrayCid: case kExternalTypedDataUint8ClampedArrayCid: + builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone, + builder.TokenPos())); value = builder.AddUnboxInstr(kUnboxedIntPtr, new Value(value), /* is_checked = */ false); value->AsUnboxInteger()->mark_truncating();
diff --git a/tests/language_2/vm/clamp_37868_test.dart b/tests/language_2/vm/clamp_37868_test.dart new file mode 100755 index 0000000..181f895 --- /dev/null +++ b/tests/language_2/vm/clamp_37868_test.dart
@@ -0,0 +1,34 @@ +// 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. + +// VMOptions=--deterministic + +import "package:expect/expect.dart"; + +import 'dart:typed_data'; + +// Found by "value-guided" DartFuzzing: incorrect clamping. +// https://github.com/dart-lang/sdk/issues/37868 +@pragma("vm:never-inline") +foo(List<int> x) => Uint8ClampedList.fromList(x); + +main() { + var x = [ + 9223372036854775807, + -9223372036854775808, + 9223372032559808513, + -9223372032559808513, + 5000000000, + -5000000000, + 2147483647, + -2147483648, + 255, + -255, + ]; + var y = foo(x); + for (int i = 0; i < y.length; i += 2) { + Expect.equals(255, y[i]); + Expect.equals(0, y[i + 1]); + } +}