mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[cfe] Uninitialized variable declarations in const functions.
Change-Id: I1c27902a0af7648b4352b0cd21691cf9f88b78fb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194460 Commit-Queue: Kallen Tu <kallentu@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com> Reviewed-by: Jake Macdonald <jakemac@google.com>
This commit is contained in:
parent
77cfcff92f
commit
9bd43c3071
11 changed files with 198 additions and 6 deletions
|
@ -3607,8 +3607,11 @@ class StatementConstantEvaluator extends StatementVisitor<ExecutionStatus> {
|
|||
|
||||
@override
|
||||
ExecutionStatus visitVariableDeclaration(VariableDeclaration node) {
|
||||
Constant value = evaluate(node.initializer);
|
||||
if (value is AbortConstant) return new AbortStatus(value);
|
||||
Constant value;
|
||||
if (node.initializer != null) {
|
||||
value = evaluate(node.initializer);
|
||||
if (value is AbortConstant) return new AbortStatus(value);
|
||||
}
|
||||
exprEvaluator.env.addVariableValue(node, value);
|
||||
return const ProceedStatus();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,29 @@ int function5() {
|
|||
return constant;
|
||||
}
|
||||
|
||||
const var6 = function6();
|
||||
int function6() {
|
||||
var a;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
const var7 = function7();
|
||||
int function7() {
|
||||
var a;
|
||||
var b;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
const var8 = function8();
|
||||
int function8() {
|
||||
var a;
|
||||
int? b;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
Expect.equals(var1, 4);
|
||||
Expect.equals(var1_1, 5);
|
||||
|
@ -46,4 +69,7 @@ void main() {
|
|||
Expect.equals(var3, 6);
|
||||
Expect.equals(var4, 2);
|
||||
Expect.equals(var5, -2);
|
||||
Expect.equals(var6, 2);
|
||||
Expect.equals(var7, 2);
|
||||
Expect.equals(var8, 2);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ static const field core::String var2 = #C3;
|
|||
static const field core::int var3 = #C4;
|
||||
static const field core::int var4 = #C5;
|
||||
static const field core::int var5 = #C6;
|
||||
static const field core::int var6 = #C5;
|
||||
static const field core::int var7 = #C5;
|
||||
static const field core::int var8 = #C5;
|
||||
static method function1(core::int a, core::int b) → core::int {
|
||||
core::int x = 1.{core::num::+}(a).{core::num::+}(b);
|
||||
return x;
|
||||
|
@ -32,6 +35,23 @@ static method function4() → core::int {
|
|||
static method function5() → core::int {
|
||||
return #C6;
|
||||
}
|
||||
static method function6() → core::int {
|
||||
dynamic a;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function7() → core::int {
|
||||
dynamic a;
|
||||
dynamic b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function8() → core::int {
|
||||
dynamic a;
|
||||
core::int? b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method main() → void {
|
||||
exp::Expect::equals(#C1, 4);
|
||||
exp::Expect::equals(#C2, 5);
|
||||
|
@ -39,6 +59,9 @@ static method main() → void {
|
|||
exp::Expect::equals(#C4, 6);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C6, 2.{core::int::unary-}());
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -11,6 +11,9 @@ static const field core::String var2 = #C3;
|
|||
static const field core::int var3 = #C4;
|
||||
static const field core::int var4 = #C5;
|
||||
static const field core::int var5 = #C6;
|
||||
static const field core::int var6 = #C5;
|
||||
static const field core::int var7 = #C5;
|
||||
static const field core::int var8 = #C5;
|
||||
static method function1(core::int a, core::int b) → core::int {
|
||||
core::int x = 1.{core::num::+}(a).{core::num::+}(b);
|
||||
return x;
|
||||
|
@ -32,6 +35,23 @@ static method function4() → core::int {
|
|||
static method function5() → core::int {
|
||||
return #C6;
|
||||
}
|
||||
static method function6() → core::int {
|
||||
dynamic a;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function7() → core::int {
|
||||
dynamic a;
|
||||
dynamic b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function8() → core::int {
|
||||
dynamic a;
|
||||
core::int? b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method main() → void {
|
||||
exp::Expect::equals(#C1, 4);
|
||||
exp::Expect::equals(#C2, 5);
|
||||
|
@ -39,6 +59,9 @@ static method main() → void {
|
|||
exp::Expect::equals(#C4, 6);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C6, 2.{core::int::unary-}());
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
}
|
||||
|
||||
constants {
|
||||
|
@ -51,5 +74,5 @@ constants {
|
|||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:48:23 -> IntConstant(-2)
|
||||
Extra constant evaluation: evaluated: 21, effectively constant: 1
|
||||
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:71:23 -> IntConstant(-2)
|
||||
Extra constant evaluation: evaluated: 33, effectively constant: 1
|
||||
|
|
|
@ -11,4 +11,10 @@ const var4 = function4();
|
|||
int function4() {}
|
||||
const var5 = function5();
|
||||
int function5() {}
|
||||
const var6 = function6();
|
||||
int function6() {}
|
||||
const var7 = function7();
|
||||
int function7() {}
|
||||
const var8 = function8();
|
||||
int function8() {}
|
||||
void main() {}
|
||||
|
|
|
@ -7,8 +7,14 @@ const var2 = function2();
|
|||
const var3 = function3();
|
||||
const var4 = function4();
|
||||
const var5 = function5();
|
||||
const var6 = function6();
|
||||
const var7 = function7();
|
||||
const var8 = function8();
|
||||
int function1(int a, int b) {}
|
||||
int function3() {}
|
||||
int function4() {}
|
||||
int function5() {}
|
||||
int function6() {}
|
||||
int function7() {}
|
||||
int function8() {}
|
||||
void main() {}
|
||||
|
|
|
@ -11,6 +11,9 @@ static const field core::String var2 = #C3;
|
|||
static const field core::int var3 = #C4;
|
||||
static const field core::int var4 = #C5;
|
||||
static const field core::int var5 = #C6;
|
||||
static const field core::int var6 = #C5;
|
||||
static const field core::int var7 = #C5;
|
||||
static const field core::int var8 = #C5;
|
||||
static method function1(core::int a, core::int b) → core::int {
|
||||
core::int x = 1.{core::num::+}(a).{core::num::+}(b);
|
||||
return x;
|
||||
|
@ -32,6 +35,23 @@ static method function4() → core::int {
|
|||
static method function5() → core::int {
|
||||
return #C6;
|
||||
}
|
||||
static method function6() → core::int {
|
||||
dynamic a;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function7() → core::int {
|
||||
dynamic a;
|
||||
dynamic b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function8() → core::int {
|
||||
dynamic a;
|
||||
core::int? b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method main() → void {
|
||||
exp::Expect::equals(#C1, 4);
|
||||
exp::Expect::equals(#C2, 5);
|
||||
|
@ -39,6 +59,9 @@ static method main() → void {
|
|||
exp::Expect::equals(#C4, 6);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C6, 2.{core::int::unary-}());
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -10,6 +10,9 @@ static const field core::String var2 = self::function2();
|
|||
static const field core::int var3 = self::function3();
|
||||
static const field core::int var4 = self::function4();
|
||||
static const field core::int var5 = self::function5();
|
||||
static const field core::int var6 = self::function6();
|
||||
static const field core::int var7 = self::function7();
|
||||
static const field core::int var8 = self::function8();
|
||||
static method function1(core::int a, core::int b) → core::int
|
||||
;
|
||||
static method function2() → core::String
|
||||
|
@ -20,5 +23,11 @@ static method function4() → core::int
|
|||
;
|
||||
static method function5() → core::int
|
||||
;
|
||||
static method function6() → core::int
|
||||
;
|
||||
static method function7() → core::int
|
||||
;
|
||||
static method function8() → core::int
|
||||
;
|
||||
static method main() → void
|
||||
;
|
||||
|
|
|
@ -11,6 +11,9 @@ static const field core::String var2 = #C3;
|
|||
static const field core::int var3 = #C4;
|
||||
static const field core::int var4 = #C5;
|
||||
static const field core::int var5 = #C6;
|
||||
static const field core::int var6 = #C5;
|
||||
static const field core::int var7 = #C5;
|
||||
static const field core::int var8 = #C5;
|
||||
static method function1(core::int a, core::int b) → core::int {
|
||||
core::int x = 1.{core::num::+}(a).{core::num::+}(b);
|
||||
return x;
|
||||
|
@ -32,6 +35,23 @@ static method function4() → core::int {
|
|||
static method function5() → core::int {
|
||||
return #C6;
|
||||
}
|
||||
static method function6() → core::int {
|
||||
dynamic a;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function7() → core::int {
|
||||
dynamic a;
|
||||
dynamic b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method function8() → core::int {
|
||||
dynamic a;
|
||||
core::int? b;
|
||||
a = 2;
|
||||
return a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
|
||||
}
|
||||
static method main() → void {
|
||||
exp::Expect::equals(#C1, 4);
|
||||
exp::Expect::equals(#C2, 5);
|
||||
|
@ -39,6 +59,9 @@ static method main() → void {
|
|||
exp::Expect::equals(#C4, 6);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C6, 2.{core::int::unary-}());
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
exp::Expect::equals(#C5, 2);
|
||||
}
|
||||
|
||||
constants {
|
||||
|
@ -51,5 +74,5 @@ constants {
|
|||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:48:23 -> IntConstant(-2)
|
||||
Extra constant evaluation: evaluated: 21, effectively constant: 1
|
||||
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:71:23 -> IntConstant(-2)
|
||||
Extra constant evaluation: evaluated: 33, effectively constant: 1
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2021, 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.
|
||||
|
||||
// Tests erroneous variable declaration usage within const functions.
|
||||
|
||||
// SharedOptions=--enable-experiment=const-functions
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
const var1 = fn1();
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// [cfe] Constant evaluation error:
|
||||
int fn1() {
|
||||
var a;
|
||||
return a;
|
||||
}
|
|
@ -53,6 +53,35 @@ int function5() {
|
|||
return constant;
|
||||
}
|
||||
|
||||
const var6 = function6();
|
||||
// ^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
int function6() {
|
||||
var a;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
const var7 = function7();
|
||||
// ^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
int function7() {
|
||||
var a;
|
||||
var b;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
const var8 = function8();
|
||||
// ^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
int function8() {
|
||||
var a;
|
||||
int? b;
|
||||
a = 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
Expect.equals(var1, 4);
|
||||
Expect.equals(var1_1, 5);
|
||||
|
@ -60,4 +89,7 @@ void main() {
|
|||
Expect.equals(var3, 6);
|
||||
Expect.equals(var4, 2);
|
||||
Expect.equals(var5, -2);
|
||||
Expect.equals(var6, 2);
|
||||
Expect.equals(var7, 2);
|
||||
Expect.equals(var8, 2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue