[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:
Kallen Tu 2021-04-12 15:42:26 +00:00 committed by commit-bot@chromium.org
parent 77cfcff92f
commit 9bd43c3071
11 changed files with 198 additions and 6 deletions

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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 {

View file

@ -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

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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 {

View file

@ -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
;

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}