Skip to content

Commit 31e324b

Browse files
jensjohaCommit Queue
authored andcommitted
[CFE] Fix crash on invalid this references
Change-Id: If6a323a7cc2defab3a0f7844b948719c49fef483 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395301 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent 30b0a80 commit 31e324b

File tree

37 files changed

+781
-2
lines changed

37 files changed

+781
-2
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3292,6 +3292,10 @@ class BodyBuilder extends StackListenerImpl
32923292
// semantics, such parameters introduces a new parameter with that
32933293
// name that should be resolved here.
32943294
!_context.isConstructor) {
3295+
if (declaration.isExtensionTypeInstanceMember) {
3296+
return new IncompleteErrorGenerator(
3297+
this, nameToken, fasta.messageNotAConstantExpression);
3298+
}
32953299
addProblem(
32963300
fasta.messageNotAConstantExpression, nameOffset, nameToken.length);
32973301
}
@@ -7178,8 +7182,13 @@ class BodyBuilder extends StackListenerImpl
71787182
debugEvent("ThisExpression");
71797183
if (context.isScopeReference && isDeclarationInstanceContext) {
71807184
if (thisVariable != null && !inConstructorInitializer) {
7181-
push(_createReadOnlyVariableAccess(thisVariable!, token,
7182-
offsetForToken(token), 'this', ReadOnlyAccessKind.ExtensionThis));
7185+
if (constantContext != ConstantContext.none) {
7186+
push(new IncompleteErrorGenerator(
7187+
this, token, fasta.messageThisAsIdentifier));
7188+
} else {
7189+
push(_createReadOnlyVariableAccess(thisVariable!, token,
7190+
offsetForToken(token), 'this', ReadOnlyAccessKind.ExtensionThis));
7191+
}
71837192
} else {
71847193
push(new ThisAccessGenerator(this, token, inInitializerLeftHandSide,
71857194
inFieldInitializer, inLateFieldInitializer));

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ foos
348348
forbidden
349349
forces
350350
foreground
351+
forgot
351352
forrest
352353
forth
353354
forty
@@ -577,6 +578,7 @@ oo
577578
oobar
578579
oocf
579580
ooo
581+
oops
580582
oovf
581583
opacity
582584
operate
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(String x) {
6+
int x2 = 42;
7+
8+
@x2
9+
int? a, b;
10+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:6:7: Error: Extension types can't declare instance fields
6+
// Try removing the field declaration or making it a static field
7+
// int x2 = 42;
8+
// ^^
9+
//
10+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:9:8: Error: Extension types can't declare instance fields
11+
// Try removing the field declaration or making it a static field
12+
// int? a, b;
13+
// ^
14+
//
15+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
16+
// @x2
17+
// ^^
18+
//
19+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
20+
// @x2
21+
// ^
22+
//
23+
import self as self;
24+
import "dart:core" as core;
25+
26+
extension type Foo(core::String x) {
27+
abstract extension-type-member representation-field get x() → core::String;
28+
abstract extension-type-member representation-field get x2() → core::int;
29+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
30+
@x2
31+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
32+
@x2
33+
^^"
34+
abstract extension-type-member representation-field get a() → core::int?;
35+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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+
@x2
37+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
38+
@x2
39+
^^"
40+
abstract extension-type-member representation-field get b() → core::int?;
41+
constructor • = self::Foo|constructor#;
42+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
43+
}
44+
static extension-type-member method Foo|constructor#(core::String x) → self::Foo% /* erasure=core::String, declared=! */ {
45+
lowered final self::Foo% /* erasure=core::String, declared=! */ #this = x;
46+
return #this;
47+
}
48+
static extension-type-member method Foo|constructor#_#new#tearOff(core::String x) → self::Foo% /* erasure=core::String, declared=! */
49+
return self::Foo|constructor#(x);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:6:7: Error: Extension types can't declare instance fields
6+
// Try removing the field declaration or making it a static field
7+
// int x2 = 42;
8+
// ^^
9+
//
10+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:9:8: Error: Extension types can't declare instance fields
11+
// Try removing the field declaration or making it a static field
12+
// int? a, b;
13+
// ^
14+
//
15+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
16+
// @x2
17+
// ^^
18+
//
19+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
20+
// @x2
21+
// ^
22+
//
23+
import self as self;
24+
import "dart:core" as core;
25+
26+
extension type Foo(core::String x) {
27+
abstract extension-type-member representation-field get x() → core::String;
28+
abstract extension-type-member representation-field get x2() → core::int;
29+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
30+
@x2
31+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
32+
@x2
33+
^^"
34+
abstract extension-type-member representation-field get a() → core::int?;
35+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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+
@x2
37+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
38+
@x2
39+
^^"
40+
abstract extension-type-member representation-field get b() → core::int?;
41+
constructor • = self::Foo|constructor#;
42+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
43+
}
44+
static extension-type-member method Foo|constructor#(core::String x) → self::Foo% /* erasure=core::String, declared=! */ {
45+
lowered final self::Foo% /* erasure=core::String, declared=! */ #this = x;
46+
return #this;
47+
}
48+
static extension-type-member method Foo|constructor#_#new#tearOff(core::String x) → self::Foo% /* erasure=core::String, declared=! */
49+
return self::Foo|constructor#(x);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:6:7: Error: Extension types can't declare instance fields
6+
// Try removing the field declaration or making it a static field
7+
// int x2 = 42;
8+
// ^^
9+
//
10+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:9:8: Error: Extension types can't declare instance fields
11+
// Try removing the field declaration or making it a static field
12+
// int? a, b;
13+
// ^
14+
//
15+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
16+
// @x2
17+
// ^^
18+
//
19+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
20+
// @x2
21+
// ^
22+
//
23+
import self as self;
24+
import "dart:core" as core;
25+
26+
extension type Foo(core::String x) {
27+
abstract extension-type-member representation-field get x() → core::String;
28+
abstract extension-type-member representation-field get x2() → core::int;
29+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
30+
@x2
31+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
32+
@x2
33+
^^"
34+
abstract extension-type-member representation-field get a() → core::int?;
35+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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+
@x2
37+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
38+
@x2
39+
^^"
40+
abstract extension-type-member representation-field get b() → core::int?;
41+
constructor • = self::Foo|constructor#;
42+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
43+
}
44+
static extension-type-member method Foo|constructor#(core::String x) → self::Foo% /* erasure=core::String, declared=! */
45+
;
46+
static extension-type-member method Foo|constructor#_#new#tearOff(core::String x) → self::Foo% /* erasure=core::String, declared=! */
47+
return self::Foo|constructor#(x);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:6:7: Error: Extension types can't declare instance fields
6+
// Try removing the field declaration or making it a static field
7+
// int x2 = 42;
8+
// ^^
9+
//
10+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:9:8: Error: Extension types can't declare instance fields
11+
// Try removing the field declaration or making it a static field
12+
// int? a, b;
13+
// ^
14+
//
15+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
16+
// @x2
17+
// ^^
18+
//
19+
// pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
20+
// @x2
21+
// ^
22+
//
23+
import self as self;
24+
import "dart:core" as core;
25+
26+
extension type Foo(core::String x) {
27+
abstract extension-type-member representation-field get x() → core::String;
28+
abstract extension-type-member representation-field get x2() → core::int;
29+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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.
30+
@x2
31+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
32+
@x2
33+
^^"
34+
abstract extension-type-member representation-field get a() → core::int?;
35+
@invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: 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+
@x2
37+
^" in invalid-expression "pkg/front_end/testcases/regress/invalid_this_reference_01.dart:8:4: Error: Not a constant expression.
38+
@x2
39+
^^"
40+
abstract extension-type-member representation-field get b() → core::int?;
41+
constructor • = self::Foo|constructor#;
42+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
43+
}
44+
static extension-type-member method Foo|constructor#(core::String x) → self::Foo% /* erasure=core::String, declared=! */ {
45+
lowered final self::Foo% /* erasure=core::String, declared=! */ #this = x;
46+
return #this;
47+
}
48+
static extension-type-member method Foo|constructor#_#new#tearOff(core::String x) → self::Foo% /* erasure=core::String, declared=! */
49+
return self::Foo|constructor#(x);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension type Foo(String x) {
2+
int x2 = 42;
3+
@x2
4+
int? a, b;
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension type Foo(String x) {
2+
@x2
3+
int? a, b;
4+
int x2 = 42;
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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(String x) {
6+
static const int x1 = 42;
7+
int x2 = 42;
8+
9+
int bar1({int baz = x2}) => 42;
10+
int bar2({int baz = x /* oops forgot the 1 */}) => 42;
11+
}

0 commit comments

Comments
 (0)