[CFE] Error on bitwise or shift operation on a double constant.
Fixes https://github.com/dart-lang/sdk/issues/36823 Change-Id: I9aeb34b9f80261889434f85bf39af3d78a38202e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112391 Reviewed-by: Mayank Patke <fishythefish@google.com> Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
2d9246000f
commit
e611357309
@@ -1215,9 +1215,11 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
unevaluatedArguments(arguments, {}, node.arguments.types)));
|
||||
}
|
||||
|
||||
final String op = node.name.name;
|
||||
|
||||
// Handle == and != first (it's common between all types). Since `a != b` is
|
||||
// parsed as `!(a == b)` it is handled implicitly through ==.
|
||||
if (arguments.length == 1 && node.name.name == '==') {
|
||||
if (arguments.length == 1 && op == '==') {
|
||||
final right = arguments[0];
|
||||
|
||||
// [DoubleConstant] uses [identical] to determine equality, so we need two
|
||||
@@ -1250,7 +1252,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
// This is a white-listed set of methods we need to support on constants.
|
||||
if (receiver is StringConstant) {
|
||||
if (arguments.length == 1) {
|
||||
switch (node.name.name) {
|
||||
switch (op) {
|
||||
case '+':
|
||||
final Constant other = arguments[0];
|
||||
if (other is StringConstant) {
|
||||
@@ -1268,7 +1270,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
}
|
||||
} else if (receiver is IntConstant || receiver is JavaScriptIntConstant) {
|
||||
if (arguments.length == 0) {
|
||||
switch (node.name.name) {
|
||||
switch (op) {
|
||||
case 'unary-':
|
||||
if (targetingJavaScript) {
|
||||
BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
|
||||
@@ -1290,7 +1292,6 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
}
|
||||
} else if (arguments.length == 1) {
|
||||
final Constant other = arguments[0];
|
||||
final op = node.name.name;
|
||||
if (other is IntConstant || other is JavaScriptIntConstant) {
|
||||
if ((op == '<<' || op == '>>' || op == '>>>')) {
|
||||
var receiverValue = receiver is IntConstant
|
||||
@@ -1342,7 +1343,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
.toUnsigned(32)
|
||||
.toInt();
|
||||
return evaluateBinaryBitOperation(
|
||||
node.name.name, receiverValue, otherValue, node);
|
||||
op, receiverValue, otherValue, node);
|
||||
case '<<':
|
||||
case '>>':
|
||||
case '>>>':
|
||||
@@ -1361,7 +1362,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
: (other as JavaScriptIntConstant).bigIntValue.toInt();
|
||||
|
||||
return evaluateBinaryShiftOperation(
|
||||
node.name.name, receiverValue, otherValue, node,
|
||||
op, receiverValue, otherValue, node,
|
||||
negativeReceiver: negative);
|
||||
default:
|
||||
num receiverValue = receiver is IntConstant
|
||||
@@ -1371,26 +1372,46 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
? other.value
|
||||
: (other as DoubleConstant).value;
|
||||
return evaluateBinaryNumericOperation(
|
||||
node.name.name, receiverValue, otherValue, node);
|
||||
op, receiverValue, otherValue, node);
|
||||
}
|
||||
} else if (other is DoubleConstant) {
|
||||
if ((op == '|' || op == '&' || op == '^') ||
|
||||
(op == '<<' || op == '>>' || op == '>>>')) {
|
||||
return report(
|
||||
node,
|
||||
templateConstEvalInvalidBinaryOperandType.withArguments(
|
||||
op,
|
||||
other,
|
||||
typeEnvironment.intType,
|
||||
other.getType(typeEnvironment)));
|
||||
}
|
||||
num receiverValue = receiver is IntConstant
|
||||
? receiver.value
|
||||
: (receiver as DoubleConstant).value;
|
||||
return evaluateBinaryNumericOperation(
|
||||
node.name.name, receiverValue, other.value, node);
|
||||
op, receiverValue, other.value, node);
|
||||
}
|
||||
return report(
|
||||
node,
|
||||
templateConstEvalInvalidBinaryOperandType.withArguments(
|
||||
node.name.name,
|
||||
op,
|
||||
receiver,
|
||||
typeEnvironment.numType,
|
||||
other.getType(typeEnvironment)));
|
||||
}
|
||||
} else if (receiver is DoubleConstant) {
|
||||
if ((op == '|' || op == '&' || op == '^') ||
|
||||
(op == '<<' || op == '>>' || op == '>>>')) {
|
||||
return report(
|
||||
node,
|
||||
templateConstEvalInvalidBinaryOperandType.withArguments(
|
||||
op,
|
||||
receiver,
|
||||
typeEnvironment.intType,
|
||||
receiver.getType(typeEnvironment)));
|
||||
}
|
||||
if (arguments.length == 0) {
|
||||
switch (node.name.name) {
|
||||
switch (op) {
|
||||
case 'unary-':
|
||||
return canonicalize(makeDoubleConstant(-receiver.value));
|
||||
}
|
||||
@@ -1402,12 +1423,12 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
? other.value
|
||||
: (other as DoubleConstant).value;
|
||||
return evaluateBinaryNumericOperation(
|
||||
node.name.name, receiver.value, value, node);
|
||||
op, receiver.value, value, node);
|
||||
}
|
||||
return report(
|
||||
node,
|
||||
templateConstEvalInvalidBinaryOperandType.withArguments(
|
||||
node.name.name,
|
||||
op,
|
||||
receiver,
|
||||
typeEnvironment.numType,
|
||||
other.getType(typeEnvironment)));
|
||||
@@ -1416,7 +1437,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
if (arguments.length == 1) {
|
||||
final Constant other = arguments[0];
|
||||
if (other is BoolConstant) {
|
||||
switch (node.name.name) {
|
||||
switch (op) {
|
||||
case '|':
|
||||
return canonicalize(
|
||||
new BoolConstant(receiver.value || other.value));
|
||||
@@ -1433,10 +1454,8 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
|
||||
return report(node, messageConstEvalNullValue);
|
||||
}
|
||||
|
||||
return report(
|
||||
node,
|
||||
templateConstEvalInvalidMethodInvocation.withArguments(
|
||||
node.name.name, receiver));
|
||||
return report(node,
|
||||
templateConstEvalInvalidMethodInvocation.withArguments(op, receiver));
|
||||
}
|
||||
|
||||
visitLogicalExpression(LogicalExpression node) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
|
||||
// SharedOptions=--enable-experiment=constant-update-2018,triple-shift
|
||||
|
||||
main() {
|
||||
const dynamic i1 = 3;
|
||||
const dynamic i2 = 2;
|
||||
const dynamic d1 = 3.3;
|
||||
const dynamic d2 = 2.2;
|
||||
|
||||
const sum = 0 + //
|
||||
(i1 | i2) + //# ii1: ok
|
||||
(i1 & i2) + //# ii2: ok
|
||||
(i1 ^ i2) + //# ii3: ok
|
||||
(i1 << i2) + //# ii4: ok
|
||||
(i1 >> i2) + //# ii5: ok
|
||||
(i1 >>> i2) + //# ii6: ok
|
||||
(i1 | d2) + //# id1: compile-time error
|
||||
(i1 & d2) + //# id2: compile-time error
|
||||
(i1 ^ d2) + //# id3: compile-time error
|
||||
(i1 << d2) + //# id4: compile-time error
|
||||
(i1 >> d2) + //# id5: compile-time error
|
||||
(i1 >>> d2) + //# id6: compile-time error
|
||||
(d1 | i2) + //# di1: compile-time error
|
||||
(d1 & i2) + //# di2: compile-time error
|
||||
(d1 ^ i2) + //# di3: compile-time error
|
||||
(d1 << i2) + //# di4: compile-time error
|
||||
(d1 >> i2) + //# di5: compile-time error
|
||||
(d1 >>> i2) + //# di6: compile-time error
|
||||
(d1 | d2) + //# dd1: compile-time error
|
||||
(d1 & d2) + //# dd2: compile-time error
|
||||
(d1 ^ d2) + //# dd3: compile-time error
|
||||
(d1 << d2) + //# dd4: compile-time error
|
||||
(d1 >> d2) + //# dd5: compile-time error
|
||||
(d1 >>> d2) + //# dd6: compile-time error
|
||||
0;
|
||||
print(sum);
|
||||
}
|
||||
@@ -30,6 +30,10 @@ cascaded_forwarding_stubs_test: CompileTimeError
|
||||
const_cast2_test/01: CompileTimeError
|
||||
const_cast2_test/none: CompileTimeError
|
||||
const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
|
||||
const_double_in_int_op_test/dd6: Skip # Triple shift
|
||||
const_double_in_int_op_test/di6: Skip # Triple shift
|
||||
const_double_in_int_op_test/id6: Skip # Triple shift
|
||||
const_double_in_int_op_test/ii6: Skip # Triple shift
|
||||
covariant_override/tear_off_type_test: RuntimeError # Issue 28395
|
||||
covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
|
||||
deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920
|
||||
|
||||
Reference in New Issue
Block a user