Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a3d13fb

Browse files
askeksacommit-bot@chromium.org
authored andcommitted
[CFE] Option to report error on unevaluated constants.
Fixes dart-lang/sdk#36565 Change-Id: I011e4b5242a02e06392af01ad77615c694fb62ba Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99121 Auto-Submit: Aske Simon Christensen <askesc@google.com> Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Aske Simon Christensen <askesc@google.com>
1 parent 394f88d commit a3d13fb

File tree

7 files changed

+41
-4
lines changed

7 files changed

+41
-4
lines changed

pkg/front_end/lib/src/api_prototype/compiler_options.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ class CompilerOptions {
134134
/// unevaluated and can be evaluated by a constant evaluator later.
135135
Map<String, String> environmentDefines = null;
136136

137+
/// Report an error if a constant could not be evaluated (either because it
138+
/// is an environment constant and no environment was specified, or because
139+
/// it refers to a constructor or variable initializer that is not available).
140+
bool errorOnUnevaluatedConstant = false;
141+
137142
/// The target platform that will consume the compiled code.
138143
///
139144
/// Used to provide platform-specific details to the compiler like:

pkg/front_end/lib/src/base/processed_options.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ class ProcessedOptions {
184184

185185
final Map<String, String> environmentDefines;
186186

187+
bool get errorOnUnevaluatedConstant => _raw.errorOnUnevaluatedConstant;
188+
187189
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
188190
ProcessedOptions({CompilerOptions options, List<Uri> inputs, this.output})
189191
: this._raw = options ?? new CompilerOptions(),

pkg/front_end/lib/src/fasta/fasta_codes_generated.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,14 @@ const MessageCode messageConstEvalNullValue = const MessageCode(
16341634
analyzerCodes: <String>["CONST_EVAL_THROWS_EXCEPTION"],
16351635
message: r"""Null value during constant evaluation.""");
16361636

1637+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1638+
const Code<Null> codeConstEvalUnevaluated = messageConstEvalUnevaluated;
1639+
1640+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1641+
const MessageCode messageConstEvalUnevaluated = const MessageCode(
1642+
"ConstEvalUnevaluated",
1643+
message: r"""Could not evaluate constant expression.""");
1644+
16371645
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
16381646
const Template<
16391647
Message Function(

pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import '../fasta_codes.dart'
4545
messageConstEvalNotListOrSetInSpread,
4646
messageConstEvalNotMapInSpread,
4747
messageConstEvalNullValue,
48+
messageConstEvalUnevaluated,
4849
noLength,
4950
templateConstEvalDeferredLibrary,
5051
templateConstEvalDuplicateElement,
@@ -83,6 +84,7 @@ Component transformComponent(Component component, ConstantsBackend backend,
8384
bool enableAsserts: false,
8485
bool evaluateAnnotations: true,
8586
bool desugarSets: false,
87+
bool errorOnUnevaluatedConstant: false,
8688
CoreTypes coreTypes,
8789
ClassHierarchy hierarchy}) {
8890
coreTypes ??= new CoreTypes(component);
@@ -95,6 +97,7 @@ Component transformComponent(Component component, ConstantsBackend backend,
9597
keepFields: keepFields,
9698
enableAsserts: enableAsserts,
9799
desugarSets: desugarSets,
100+
errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
98101
evaluateAnnotations: evaluateAnnotations);
99102
return component;
100103
}
@@ -109,6 +112,7 @@ void transformLibraries(
109112
bool keepVariables: false,
110113
bool evaluateAnnotations: true,
111114
bool desugarSets: false,
115+
bool errorOnUnevaluatedConstant: false,
112116
bool enableAsserts: false}) {
113117
final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
114118
backend,
@@ -117,6 +121,7 @@ void transformLibraries(
117121
keepVariables,
118122
evaluateAnnotations,
119123
desugarSets,
124+
errorOnUnevaluatedConstant,
120125
typeEnvironment,
121126
enableAsserts,
122127
errorReporter);
@@ -150,6 +155,7 @@ class ConstantsTransformer extends Transformer {
150155
final bool keepVariables;
151156
final bool evaluateAnnotations;
152157
final bool desugarSets;
158+
final bool errorOnUnevaluatedConstant;
153159

154160
ConstantsTransformer(
155161
ConstantsBackend backend,
@@ -158,12 +164,14 @@ class ConstantsTransformer extends Transformer {
158164
this.keepVariables,
159165
this.evaluateAnnotations,
160166
this.desugarSets,
167+
this.errorOnUnevaluatedConstant,
161168
this.typeEnvironment,
162169
bool enableAsserts,
163170
ErrorReporter errorReporter)
164171
: constantEvaluator = new ConstantEvaluator(backend, environmentDefines,
165172
typeEnvironment, enableAsserts, errorReporter,
166-
desugarSets: desugarSets);
173+
desugarSets: desugarSets,
174+
errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
167175

168176
// Transform the library/class members:
169177

@@ -454,6 +462,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
454462
final ConstantsBackend backend;
455463
final NumberSemantics numberSemantics;
456464
Map<String, String> environmentDefines;
465+
final bool errorOnUnevaluatedConstant;
457466
final CoreTypes coreTypes;
458467
final TypeEnvironment typeEnvironment;
459468
final bool enableAsserts;
@@ -490,7 +499,7 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
490499

491500
ConstantEvaluator(this.backend, this.environmentDefines, this.typeEnvironment,
492501
this.enableAsserts, this.errorReporter,
493-
{this.desugarSets = false})
502+
{this.desugarSets = false, this.errorOnUnevaluatedConstant = false})
494503
: numberSemantics = backend.numberSemantics,
495504
coreTypes = typeEnvironment.coreTypes,
496505
canonicalizationCache = <Constant, Constant>{},
@@ -539,7 +548,11 @@ class ConstantEvaluator extends RecursiveVisitor<Constant> {
539548
seenUnevaluatedChild = false;
540549
lazyDepth = 0;
541550
try {
542-
return _evaluateSubexpression(node);
551+
Constant result = _evaluateSubexpression(node);
552+
if (errorOnUnevaluatedConstant && result is UnevaluatedConstant) {
553+
return report(node, messageConstEvalUnevaluated);
554+
}
555+
return result;
543556
} on _AbortDueToError catch (e) {
544557
final Uri uri = getFileUri(e.node);
545558
final int fileOffset = getFileOffset(uri, e.node);

pkg/front_end/lib/src/fasta/kernel/kernel_target.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ class KernelTarget extends TargetImplementation {
136136
final Map<String, String> environmentDefines =
137137
CompilerContext.current.options.environmentDefines;
138138

139+
final bool errorOnUnevaluatedConstant =
140+
CompilerContext.current.options.errorOnUnevaluatedConstant;
141+
139142
final bool enableAsserts = CompilerContext.current.options.enableAsserts;
140143

141144
final List<Object> clonedFormals = <Object>[];
@@ -777,7 +780,8 @@ class KernelTarget extends TargetImplementation {
777780
environment,
778781
new KernelConstantErrorReporter(loader),
779782
enableAsserts: enableAsserts,
780-
desugarSets: !backendTarget.supportsSetLiterals);
783+
desugarSets: !backendTarget.supportsSetLiterals,
784+
errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
781785
ticker.logMs("Evaluated constants");
782786
}
783787
backendTarget.performModularTransformationsOnLibraries(

pkg/front_end/messages.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ ConstEvalNonConstantVariableGet/example: Fail
9393
ConstEvalNotListOrSetInSpread/example: Fail
9494
ConstEvalNotMapInSpread/example: Fail
9595
ConstEvalNullValue/example: Fail
96+
ConstEvalUnevaluated/analyzerCode: Fail
97+
ConstEvalUnevaluated/example: Fail
9698
ConstEvalZeroDivisor/example: Fail
9799
ConstFieldWithoutInitializer/example: Fail
98100
ConstructorNotFound/example: Fail

pkg/front_end/messages.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ ConstEvalIterationInConstMap:
193193
template: "Iteration can't be used in a constant map."
194194
analyzerCode: NON_CONSTANT_MAP_ELEMENT
195195

196+
ConstEvalUnevaluated:
197+
template: "Could not evaluate constant expression."
198+
196199
NotConstantExpression:
197200
template: "#string is not a constant expression."
198201
analyzerCode: NOT_CONSTANT_EXPRESSION

0 commit comments

Comments
 (0)