[CFE] Check for null in constant evaluation
Change-Id: Iecd63572a29d605bb48dd79f9cd07f135bc6fc68
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/95520
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 574152c..7dd32d8 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1423,6 +1423,15 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalNullValue = messageConstEvalNullValue;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalNullValue = const MessageCode(
+ "ConstEvalNullValue",
+ analyzerCodes: <String>["CONST_EVAL_THROWS_EXCEPTION"],
+ message: r"""Null value during constant evaluation.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String string,
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index df58f84..d202376 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -39,6 +39,7 @@
messageConstEvalCircularity,
messageConstEvalContext,
messageConstEvalFailedAssertion,
+ messageConstEvalNullValue,
noLength,
templateConstEvalDeferredLibrary,
templateConstEvalDuplicateKey,
@@ -1131,7 +1132,10 @@
typeEnvironment.numType,
other.getType(typeEnvironment)));
}
+ } else if (receiver is NullConstant) {
+ return report(node, messageConstEvalNullValue);
}
+
return report(
node,
templateConstEvalInvalidMethodInvocation.withArguments(
@@ -1248,6 +1252,8 @@
node,
new PropertyGet(
unique(receiver.expression), node.name, node.interfaceTarget));
+ } else if (receiver is NullConstant) {
+ return report(node, messageConstEvalNullValue);
}
throw 'Could not evaluate property get on $receiver.';
}
@@ -1396,8 +1402,9 @@
if (value == null) return nullConstant;
return canonicalize(new StringConstant(value));
}
+ } else if (name is NullConstant) {
+ return report(node, messageConstEvalNullValue);
}
- // TODO(askesc): Give more meaningful error message if name is null.
} else {
// Leave environment constant unevaluated.
return unevaluated(
@@ -1484,6 +1491,8 @@
return unevaluated(node,
new Instantiation(unique(constant.expression), node.typeArguments));
}
+ // The inner expression in an instantiation can never be null, since
+ // instantiations are only inferred on direct references to declarations.
throw new Exception(
'Only tear-off constants can be partially instantiated.');
}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index cfa04f1..88cbda7 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -81,6 +81,7 @@
ConstEvalNegativeShift/example: Fail
ConstEvalNonConstantLiteral/example: Fail
ConstEvalNonConstantVariableGet/example: Fail
+ConstEvalNullValue/example: Fail
ConstEvalZeroDivisor/example: Fail
ConstFieldWithoutInitializer/example: Fail
ConstructorNotFound/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 195f967..304ad72 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -150,6 +150,10 @@
template: "Constant expression depends on itself."
analyzerCode: RECURSIVE_COMPILE_TIME_CONSTANT
+ConstEvalNullValue:
+ template: "Null value during constant evaluation."
+ analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+
NotConstantExpression:
template: "#string is not a constant expression."
analyzerCode: NOT_CONSTANT_EXPRESSION