mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:06:59 +00:00
[VM] Catch errors for integer operations in kernel2kernel constant evaluator
Issue https://github.com/dart-lang/sdk/issues/33481 Closes https://github.com/dart-lang/sdk/issues/33469 Change-Id: I7ca9825a0aa5f062732a759b4dd116e716a0d1b3 Reviewed-on: https://dart-review.googlesource.com/60580 Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
parent
f288124d5a
commit
b172a42881
|
@ -946,6 +946,34 @@ Message _withArgumentsConstEvalInvalidType(
|
|||
arguments: {'constant': constant, 'type': _type, 'type2': _type2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
String string,
|
||||
String string2,
|
||||
String
|
||||
string3)> templateConstEvalNegativeShift = const Template<
|
||||
Message Function(String string, String string2, String string3)>(
|
||||
messageTemplate:
|
||||
r"""Binary operator '#string' on '#string2' requires non-negative operand, but was '#string3'.""",
|
||||
withArguments: _withArgumentsConstEvalNegativeShift);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String string, String string2, String string3)>
|
||||
codeConstEvalNegativeShift =
|
||||
const Code<Message Function(String string, String string2, String string3)>(
|
||||
"ConstEvalNegativeShift", templateConstEvalNegativeShift,
|
||||
dart2jsCode: "INVALID_CONSTANT_SHIFT");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsConstEvalNegativeShift(
|
||||
String string, String string2, String string3) {
|
||||
return new Message(codeConstEvalNegativeShift,
|
||||
message:
|
||||
"""Binary operator '${string}' on '${string2}' requires non-negative operand, but was '${string3}'.""",
|
||||
arguments: {'string': string, 'string2': string2, 'string3': string3});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
|
@ -970,6 +998,33 @@ Message _withArgumentsConstEvalNonConstantLiteral(String string) {
|
|||
arguments: {'string': string});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
String string,
|
||||
String
|
||||
string2)> templateConstEvalZeroDivisor = const Template<
|
||||
Message Function(String string, String string2)>(
|
||||
messageTemplate:
|
||||
r"""Binary operator '#string' on '#string2' requires non-zero divisor, but divisor was '0'.""",
|
||||
withArguments: _withArgumentsConstEvalZeroDivisor);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String string, String string2)>
|
||||
codeConstEvalZeroDivisor =
|
||||
const Code<Message Function(String string, String string2)>(
|
||||
"ConstEvalZeroDivisor", templateConstEvalZeroDivisor,
|
||||
analyzerCode: "CONST_EVAL_THROWS_IDBZE",
|
||||
dart2jsCode: "INVALID_CONSTANT_DIV");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsConstEvalZeroDivisor(String string, String string2) {
|
||||
return new Message(codeConstEvalZeroDivisor,
|
||||
message:
|
||||
"""Binary operator '${string}' on '${string2}' requires non-zero divisor, but divisor was '0'.""",
|
||||
arguments: {'string': string, 'string2': string2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeConstFactory = messageConstFactory;
|
||||
|
||||
|
|
|
@ -80,8 +80,11 @@ ConstEvalInvalidStringInterpolationOperand/dart2jsCode: Fail
|
|||
ConstEvalInvalidStringInterpolationOperand/example: Fail
|
||||
ConstEvalInvalidType/analyzerCode: Fail # CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / ...
|
||||
ConstEvalInvalidType/example: Fail
|
||||
ConstEvalNegativeShift/analyzerCode: Fail # http://dartbug.com/33481
|
||||
ConstEvalNegativeShift/example: Fail
|
||||
ConstEvalNonConstantLiteral/dart2jsCode: Fail
|
||||
ConstEvalNonConstantLiteral/example: Fail
|
||||
ConstEvalZeroDivisor/example: Fail
|
||||
ConstFieldWithoutInitializer/example: Fail
|
||||
ConstructorNotFound/analyzerCode: Fail
|
||||
ConstructorNotFound/example: Fail
|
||||
|
|
|
@ -102,6 +102,15 @@ ConstEvalInvalidType:
|
|||
ConstEvalInvalidBinaryOperandType:
|
||||
template: "Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'."
|
||||
|
||||
ConstEvalZeroDivisor:
|
||||
template: "Binary operator '#string' on '#string2' requires non-zero divisor, but divisor was '0'."
|
||||
dart2jsCode: INVALID_CONSTANT_DIV
|
||||
analyzerCode: CONST_EVAL_THROWS_IDBZE
|
||||
|
||||
ConstEvalNegativeShift:
|
||||
template: "Binary operator '#string' on '#string2' requires non-negative operand, but was '#string3'."
|
||||
dart2jsCode: INVALID_CONSTANT_SHIFT
|
||||
|
||||
ConstEvalInvalidMethodInvocation:
|
||||
template: "The method '#string' can't be invoked on '#constant' within a const context."
|
||||
analyzerCode: UNDEFINED_OPERATOR
|
||||
|
|
|
@ -719,8 +719,14 @@ class ConstantEvaluator extends RecursiveVisitor {
|
|||
}
|
||||
} else if (arguments.length == 1) {
|
||||
final Constant other = arguments[0];
|
||||
final op = node.name.name;
|
||||
if (other is IntConstant) {
|
||||
switch (node.name.name) {
|
||||
if ((op == '<<' || op == '>>') && other.value < 0) {
|
||||
errorReporter.negativeShift(contextChain,
|
||||
node.arguments.positional.first, receiver, op, other);
|
||||
throw const _AbortCurrentEvaluation();
|
||||
}
|
||||
switch (op) {
|
||||
case '|':
|
||||
return canonicalize(
|
||||
new IntConstant(receiver.value | other.value));
|
||||
|
@ -739,12 +745,18 @@ class ConstantEvaluator extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
if (other is IntConstant || other is DoubleConstant) {
|
||||
final num value = (other is IntConstant)
|
||||
? other.value
|
||||
: (other as DoubleConstant).value;
|
||||
if (other is IntConstant) {
|
||||
if (other.value == 0 && (op == '%' || op == '~/')) {
|
||||
errorReporter.zeroDivisor(
|
||||
contextChain, node.arguments.positional.first, receiver, op);
|
||||
throw const _AbortCurrentEvaluation();
|
||||
}
|
||||
|
||||
return evaluateBinaryNumericOperation(
|
||||
node.name.name, receiver.value, value, node);
|
||||
node.name.name, receiver.value, other.value, node);
|
||||
} else if (other is DoubleConstant) {
|
||||
return evaluateBinaryNumericOperation(
|
||||
node.name.name, receiver.value, other.value, node);
|
||||
}
|
||||
|
||||
errorReporter.invalidBinaryOperandType(
|
||||
|
@ -1150,9 +1162,6 @@ class ConstantEvaluator extends RecursiveVisitor {
|
|||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static const kMaxInt64 = (1 << 63) - 1;
|
||||
static const kMinInt64 = -(1 << 63);
|
||||
}
|
||||
|
||||
/// Holds the necessary information for a constant object, namely
|
||||
|
@ -1256,6 +1265,10 @@ abstract class ErrorReporter {
|
|||
List<TreeNode> context, TreeNode node, Procedure target);
|
||||
invalidStringInterpolationOperand(
|
||||
List<TreeNode> context, TreeNode node, Constant constant);
|
||||
zeroDivisor(
|
||||
List<TreeNode> context, TreeNode node, IntConstant receiver, String op);
|
||||
negativeShift(List<TreeNode> context, TreeNode node, IntConstant receiver,
|
||||
String op, IntConstant argument);
|
||||
nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
|
||||
duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
|
||||
failedAssertion(List<TreeNode> context, TreeNode node, String message);
|
||||
|
@ -1323,6 +1336,24 @@ abstract class ErrorReporterBase implements ErrorReporter {
|
|||
node);
|
||||
}
|
||||
|
||||
zeroDivisor(
|
||||
List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
|
||||
report(
|
||||
context,
|
||||
"Binary operator '$op' on '${receiver.value}' requires non-zero "
|
||||
"divisor, but divisor was '0'.",
|
||||
node);
|
||||
}
|
||||
|
||||
negativeShift(List<TreeNode> context, TreeNode node, IntConstant receiver,
|
||||
String op, IntConstant argument) {
|
||||
report(
|
||||
context,
|
||||
"Binary operator '$op' on '${receiver.value}' requires non-negative "
|
||||
"operand, but was '${argument.value}'.",
|
||||
node);
|
||||
}
|
||||
|
||||
nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
|
||||
report(
|
||||
context,
|
||||
|
|
|
@ -27,6 +27,7 @@ import 'package:kernel/ast.dart'
|
|||
DartType,
|
||||
Field,
|
||||
FileUriNode,
|
||||
IntConstant,
|
||||
Procedure,
|
||||
StaticGet,
|
||||
TreeNode;
|
||||
|
@ -283,6 +284,20 @@ class ForwardConstantEvaluationErrors implements constants.ErrorReporter {
|
|||
reportIt(context, message, node);
|
||||
}
|
||||
|
||||
zeroDivisor(
|
||||
List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
|
||||
final message = codes.templateConstEvalZeroDivisor
|
||||
.withArguments(op, '${receiver.value}');
|
||||
reportIt(context, message, node);
|
||||
}
|
||||
|
||||
negativeShift(List<TreeNode> context, TreeNode node, IntConstant receiver,
|
||||
String op, IntConstant argument) {
|
||||
final message = codes.templateConstEvalNegativeShift
|
||||
.withArguments(op, '${receiver.value}', '${argument.value}');
|
||||
reportIt(context, message, node);
|
||||
}
|
||||
|
||||
nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
|
||||
final message =
|
||||
codes.templateConstEvalNonConstantLiteral.withArguments(klass);
|
||||
|
|
|
@ -142,6 +142,9 @@ vm/debug_break_vm_test/*: Skip
|
|||
vm/lazy_deopt_with_exception_test: Pass
|
||||
vm/reflect_core_vm_test: CompileTimeError
|
||||
vm/regress_27201_test: SkipByDesign # Loads bad library, so will always crash.
|
||||
vm/regress_33469_test/01: Crash # http://dartbug.com/33481
|
||||
vm/regress_33469_test/02: Crash # http://dartbug.com/33481
|
||||
vm/regress_33469_test/03: MissingCompileTimeError # http://dartbug.com/33481
|
||||
void_type_override_test/00: MissingCompileTimeError
|
||||
void_type_override_test/00b: MissingCompileTimeError
|
||||
void_type_override_test/01: MissingCompileTimeError
|
||||
|
|
|
@ -212,6 +212,10 @@ implicit_creation/implicit_const_not_default_values_test/e4: MissingCompileTimeE
|
|||
implicit_creation/implicit_const_not_default_values_test/e5: MissingCompileTimeError
|
||||
implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
|
||||
implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
|
||||
vm/regress_33469_test/01: MissingCompileTimeError
|
||||
vm/regress_33469_test/02: MissingCompileTimeError
|
||||
vm/regress_33469_test/03: MissingCompileTimeError
|
||||
vm/regress_33469_test/04: MissingCompileTimeError
|
||||
|
||||
[ $fasta ]
|
||||
abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32014.
|
||||
|
@ -805,8 +809,8 @@ mock_writable_final_private_field_test: RuntimeError # Issue 30849
|
|||
named_constructor_test/01: MissingRuntimeError # Fasta bug: Bad compilation of constructor reference.
|
||||
named_parameters_default_eq_test/none: RuntimeError
|
||||
nested_generic_closure_test: RuntimeError
|
||||
no_main_test/01: Skip
|
||||
no_main_test/01: DartkCrash
|
||||
no_main_test/01: Skip
|
||||
no_such_method_mock_test: RuntimeError # Issue 31426
|
||||
null_no_such_method_test: CompileTimeError # Issue 31533
|
||||
override_inheritance_field_test/04: CompileTimeError # Issue 31616
|
||||
|
|
15
tests/language_2/vm/regress_33469_test.dart
Normal file
15
tests/language_2/vm/regress_33469_test.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2018, 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.
|
||||
|
||||
class X {
|
||||
final x;
|
||||
const X(this.x);
|
||||
}
|
||||
|
||||
void main() {
|
||||
print(const X(1 << -1).x); /// 01: compile-time error
|
||||
print(const X(1 >> -1).x); /// 02: compile-time error
|
||||
print(const X(1 % 0).x); /// 03: compile-time error
|
||||
print(const X(1 ~/ 0).x); /// 04: compile-time error
|
||||
}
|
Loading…
Reference in a new issue