Skip to content

Commit 3572482

Browse files
jensjohaCommit Queue
authored andcommitted
[CFE] Fix crash when metadata references locals in extension type
Having metadata on several variables means it has to be cloned which (used to) crash. Change-Id: I0ed1d4b51cec98adb23674d144d3970d3db9d69d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398060 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent eb54636 commit 3572482

8 files changed

+162
-1
lines changed

pkg/front_end/lib/src/kernel/body_builder.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3288,7 +3288,7 @@ class BodyBuilder extends StackListenerImpl
32883288
VariableBuilder variableBuilder = declaration as VariableBuilder;
32893289
if (constantContext != ConstantContext.none &&
32903290
!variableBuilder.isConst &&
3291-
!_context.isConstructor &&
3291+
!(_context.isConstructor && inFieldInitializer) &&
32923292
!libraryFeatures.constFunctions.isEnabled) {
32933293
return new IncompleteErrorGenerator(
32943294
this, nameToken, cfe.messageNotAConstantExpression);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension type Foo._(int _x) {
6+
Foo(this._x, int bar){
7+
@bar
8+
int a1, a2;
9+
}
10+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: Not a constant expression.
6+
// @bar
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
10+
// @bar
11+
// ^
12+
//
13+
import self as self;
14+
import "dart:core" as core;
15+
16+
extension type Foo(core::int _x) {
17+
abstract extension-type-member representation-field get _x() → core::int;
18+
constructor _ = self::Foo|constructor#_;
19+
constructor tearoff _ = self::Foo|constructor#_#_#tearOff;
20+
constructor • = self::Foo|constructor#;
21+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
22+
}
23+
static extension-type-member method Foo|constructor#_(core::int _x) → self::Foo% /* erasure=core::int, declared=! */ {
24+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
25+
return #this;
26+
}
27+
static extension-type-member method Foo|constructor#_#_#tearOff(core::int _x) → self::Foo% /* erasure=core::int, declared=! */
28+
return self::Foo|constructor#_(_x);
29+
static extension-type-member method Foo|constructor#(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */ {
30+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
31+
{
32+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
33+
@bar
34+
^" core::int a1;
35+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
36+
@bar
37+
^" core::int a2;
38+
}
39+
return #this;
40+
}
41+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */
42+
return self::Foo|constructor#(_x, bar);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: Not a constant expression.
6+
// @bar
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
10+
// @bar
11+
// ^
12+
//
13+
import self as self;
14+
import "dart:core" as core;
15+
16+
extension type Foo(core::int _x) {
17+
abstract extension-type-member representation-field get _x() → core::int;
18+
constructor _ = self::Foo|constructor#_;
19+
constructor tearoff _ = self::Foo|constructor#_#_#tearOff;
20+
constructor • = self::Foo|constructor#;
21+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
22+
}
23+
static extension-type-member method Foo|constructor#_(core::int _x) → self::Foo% /* erasure=core::int, declared=! */ {
24+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
25+
return #this;
26+
}
27+
static extension-type-member method Foo|constructor#_#_#tearOff(core::int _x) → self::Foo% /* erasure=core::int, declared=! */
28+
return self::Foo|constructor#_(_x);
29+
static extension-type-member method Foo|constructor#(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */ {
30+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
31+
{
32+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
33+
@bar
34+
^" core::int a1;
35+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
36+
@bar
37+
^" core::int a2;
38+
}
39+
return #this;
40+
}
41+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */
42+
return self::Foo|constructor#(_x, bar);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
extension type Foo(core::int _x) {
6+
abstract extension-type-member representation-field get _x() → core::int;
7+
constructor _ = self::Foo|constructor#_;
8+
constructor tearoff _ = self::Foo|constructor#_#_#tearOff;
9+
constructor • = self::Foo|constructor#;
10+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
11+
}
12+
static extension-type-member method Foo|constructor#_(core::int _x) → self::Foo% /* erasure=core::int, declared=! */
13+
;
14+
static extension-type-member method Foo|constructor#_#_#tearOff(core::int _x) → self::Foo% /* erasure=core::int, declared=! */
15+
return self::Foo|constructor#_(_x);
16+
static extension-type-member method Foo|constructor#(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */
17+
;
18+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */
19+
return self::Foo|constructor#(_x, bar);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: Not a constant expression.
6+
// @bar
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
10+
// @bar
11+
// ^
12+
//
13+
import self as self;
14+
import "dart:core" as core;
15+
16+
extension type Foo(core::int _x) {
17+
abstract extension-type-member representation-field get _x() → core::int;
18+
constructor _ = self::Foo|constructor#_;
19+
constructor tearoff _ = self::Foo|constructor#_#_#tearOff;
20+
constructor • = self::Foo|constructor#;
21+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
22+
}
23+
static extension-type-member method Foo|constructor#_(core::int _x) → self::Foo% /* erasure=core::int, declared=! */ {
24+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
25+
return #this;
26+
}
27+
static extension-type-member method Foo|constructor#_#_#tearOff(core::int _x) → self::Foo% /* erasure=core::int, declared=! */
28+
return self::Foo|constructor#_(_x);
29+
static extension-type-member method Foo|constructor#(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */ {
30+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = _x;
31+
{
32+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
33+
@bar
34+
^" core::int a1;
35+
@invalid-expression "pkg/front_end/testcases/regress/extension_type_metadata_references_variable.dart:7:6: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
36+
@bar
37+
^" core::int a2;
38+
}
39+
return #this;
40+
}
41+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int _x, core::int bar) → self::Foo% /* erasure=core::int, declared=! */
42+
return self::Foo|constructor#(_x, bar);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extension type Foo._(int _x) {
2+
Foo(this._x, int bar) {}
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extension type Foo._(int _x) {
2+
Foo(this._x, int bar) {}
3+
}

0 commit comments

Comments
 (0)