[VM] Report an error when accessing constructor parameters inside a constructor invocation
Closes https://github.com/dart-lang/sdk/issues/33604
Change-Id: I84034499de43ea300b278f2f922bc73c565e8bcc
Reviewed-on: https://dart-review.googlesource.com/61934
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@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 49496f9..17e0074 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1091,6 +1091,32 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
+ String
+ string)> templateConstEvalNonConstantVariableGet = const Template<
+ Message Function(String string)>(
+ messageTemplate:
+ r"""The variable '#string' is not a constant, only constant expressions are allowed.""",
+ withArguments: _withArgumentsConstEvalNonConstantVariableGet);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)>
+ codeConstEvalNonConstantVariableGet =
+ const Code<Message Function(String string)>(
+ "ConstEvalNonConstantVariableGet",
+ templateConstEvalNonConstantVariableGet,
+ analyzerCode: "NON_CONSTANT_VALUE_IN_INITIALIZER");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalNonConstantVariableGet(String string) {
+ return new Message(codeConstEvalNonConstantVariableGet,
+ message:
+ """The variable '${string}' is not a constant, only constant expressions are allowed.""",
+ 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<
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 44d3ab7..c811a73 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -84,6 +84,8 @@
ConstEvalNegativeShift/example: Fail
ConstEvalNonConstantLiteral/dart2jsCode: Fail
ConstEvalNonConstantLiteral/example: Fail
+ConstEvalNonConstantVariableGet/dart2jsCode: Fail
+ConstEvalNonConstantVariableGet/example: Fail
ConstEvalZeroDivisor/example: Fail
ConstFieldWithoutInitializer/example: Fail
ConstructorNotFound/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 637cba2..e51c39a 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -131,6 +131,10 @@
template: "This assertion failed with message: #string"
analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+ConstEvalNonConstantVariableGet:
+ template: "The variable '#string' is not a constant, only constant expressions are allowed."
+ analyzerCode: NON_CONSTANT_VALUE_IN_INITIALIZER
+
NonAsciiIdentifier:
template: "The non-ASCII character '#character' (#unicode) can't be used in identifiers, only in strings and comments."
tip: "Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)."
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index da72794..4eb3bbf 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -5200,7 +5200,7 @@
PrimitiveConstant(this.value);
- String toString() => '${this.runtimeType}($value)';
+ String toString() => '$value';
int get hashCode => value.hashCode;
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 4e62d58..212d6e8 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -413,6 +413,14 @@
}
}
+ Constant runInsideContextIfNoContext(TreeNode node, Constant fun()) {
+ if (contextChain.isEmpty) {
+ return runInsideContext(node, fun);
+ } else {
+ return fun();
+ }
+ }
+
pushContext(TreeNode contextNode) {
contextChain.add(contextNode);
}
@@ -533,11 +541,13 @@
// Start building a new instance.
return withNewInstanceBuilder(klass, typeArguments, () {
- // "Run" the constructor (and any super constructor calls), which will
- // initialize the fields of the new instance.
- handleConstructorInvocation(
- constructor, typeArguments, positionals, named);
- return canonicalize(instanceBuilder.buildInstance());
+ return runInsideContextIfNoContext(node, () {
+ // "Run" the constructor (and any super constructor calls), which will
+ // initialize the fields of the new instance.
+ handleConstructorInvocation(
+ constructor, typeArguments, positionals, named);
+ return canonicalize(instanceBuilder.buildInstance());
+ });
});
}
@@ -907,7 +917,12 @@
throw new Exception('The front-end should ensure we do not encounter a '
'variable get of a non-const variable.');
}
- return env.lookupVariable(node.variable);
+ final Constant constant = env.lookupVariable(node.variable);
+ if (constant == null) {
+ errorReporter.nonConstantVariableGet(contextChain, node, variable.name);
+ throw const _AbortCurrentEvaluation();
+ }
+ return constant;
}
visitStaticGet(StaticGet node) {
@@ -1224,9 +1239,7 @@
}
Constant lookupVariable(VariableDeclaration variable) {
- final Constant value = _variables[variable];
- assert(value != null);
- return value;
+ return _variables[variable];
}
DartType subsituteType(DartType type) {
@@ -1272,6 +1285,8 @@
nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
failedAssertion(List<TreeNode> context, TreeNode node, String message);
+ nonConstantVariableGet(
+ List<TreeNode> context, TreeNode node, String variableName);
}
abstract class ErrorReporterBase implements ErrorReporter {
@@ -1374,6 +1389,15 @@
'The assertion condition evaluated to "false" with message "$message"',
node);
}
+
+ nonConstantVariableGet(
+ List<TreeNode> context, TreeNode node, String variableName) {
+ report(
+ context,
+ 'The variable "$variableName" cannot be used inside a constant '
+ 'expression.',
+ node);
+ }
}
class _SimpleErrorReporter extends ErrorReporterBase {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 162890e..b5ff2d5 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -312,6 +312,13 @@
reportIt(context, message, node);
}
+ nonConstantVariableGet(
+ List<TreeNode> context, TreeNode node, String variableName) {
+ final message = codes.templateConstEvalNonConstantVariableGet
+ .withArguments(variableName);
+ reportIt(context, message, node);
+ }
+
reportIt(List<TreeNode> context, codes.Message message, TreeNode node) {
final Uri uri = getFileUri(node);
final int fileOffset = getFileOffset(node);
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index f059115..ca5cfe8 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -168,7 +168,6 @@
[ $compiler == dartkp ]
class_cycle_test/02: MissingCompileTimeError
class_cycle_test/03: MissingCompileTimeError
-const_constructor_nonconst_param_test/01: DartkCrash # Issue 33604
covariant_subtyping_test: RuntimeError
duplicate_implements_test/01: MissingCompileTimeError
duplicate_implements_test/02: MissingCompileTimeError