Skip to content

Commit 3b707d5

Browse files
jensjohaCommit Queue
authored andcommitted
[CFE] Fix more crashes on invalid reference to this
Change-Id: I989688c815347f316da1fcea851cd6fbd207b47c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395522 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent 8e89041 commit 3b707d5

8 files changed

+206
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3291,7 +3291,8 @@ class BodyBuilder extends StackListenerImpl
32913291
// "this.field" parameters according to old semantics. Under the new
32923292
// semantics, such parameters introduces a new parameter with that
32933293
// name that should be resolved here.
3294-
!_context.isConstructor) {
3294+
(!_context.isConstructor ||
3295+
declaration.isExtensionTypeInstanceMember)) {
32953296
if (declaration.isExtensionTypeInstanceMember) {
32963297
return new IncompleteErrorGenerator(
32973298
this, nameToken, fasta.messageNotAConstantExpression);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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 foo) {
6+
Foo([foo = foo]) => 42;
7+
Foo.tester1(String s) : foo = s.length;
8+
Foo.tester2(this.foo);
9+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:3: Error: 'Foo' is already declared in this scope.
6+
// Foo([foo = foo]) => 42;
7+
// ^^^
8+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:5:19: Context: Previous declaration of 'Foo'.
9+
// extension type Foo(int foo) {
10+
// ^
11+
//
12+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:14: Error: Not a constant expression.
13+
// Foo([foo = foo]) => 42;
14+
// ^^^
15+
//
16+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:23: Error: Constructors can't have a return type.
17+
// Try removing the return type.
18+
// Foo([foo = foo]) => 42;
19+
// ^
20+
//
21+
import self as self;
22+
import "dart:core" as core;
23+
24+
extension type Foo(core::int foo) {
25+
abstract extension-type-member representation-field get foo() → core::int;
26+
constructor • = self::Foo|constructor#;
27+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
28+
constructor tester1 = self::Foo|constructor#tester1;
29+
constructor tearoff tester1 = self::Foo|constructor#_#tester1#tearOff;
30+
constructor tester2 = self::Foo|constructor#tester2;
31+
constructor tearoff tester2 = self::Foo|constructor#_#tester2#tearOff;
32+
}
33+
static extension-type-member method Foo|constructor#(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
34+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
35+
return #this;
36+
}
37+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
38+
return self::Foo|constructor#(foo);
39+
static extension-type-member method Foo|constructor#tester1(core::String s) → self::Foo% /* erasure=core::int, declared=! */ {
40+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = s.{core::String::length}{core::int};
41+
return #this;
42+
}
43+
static extension-type-member method Foo|constructor#_#tester1#tearOff(core::String s) → self::Foo% /* erasure=core::int, declared=! */
44+
return self::Foo|constructor#tester1(s);
45+
static extension-type-member method Foo|constructor#tester2(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
46+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
47+
return #this;
48+
}
49+
static extension-type-member method Foo|constructor#_#tester2#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
50+
return self::Foo|constructor#tester2(foo);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:3: Error: 'Foo' is already declared in this scope.
6+
// Foo([foo = foo]) => 42;
7+
// ^^^
8+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:5:19: Context: Previous declaration of 'Foo'.
9+
// extension type Foo(int foo) {
10+
// ^
11+
//
12+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:14: Error: Not a constant expression.
13+
// Foo([foo = foo]) => 42;
14+
// ^^^
15+
//
16+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:23: Error: Constructors can't have a return type.
17+
// Try removing the return type.
18+
// Foo([foo = foo]) => 42;
19+
// ^
20+
//
21+
import self as self;
22+
import "dart:core" as core;
23+
24+
extension type Foo(core::int foo) {
25+
abstract extension-type-member representation-field get foo() → core::int;
26+
constructor • = self::Foo|constructor#;
27+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
28+
constructor tester1 = self::Foo|constructor#tester1;
29+
constructor tearoff tester1 = self::Foo|constructor#_#tester1#tearOff;
30+
constructor tester2 = self::Foo|constructor#tester2;
31+
constructor tearoff tester2 = self::Foo|constructor#_#tester2#tearOff;
32+
}
33+
static extension-type-member method Foo|constructor#(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
34+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
35+
return #this;
36+
}
37+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
38+
return self::Foo|constructor#(foo);
39+
static extension-type-member method Foo|constructor#tester1(core::String s) → self::Foo% /* erasure=core::int, declared=! */ {
40+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = s.{core::String::length}{core::int};
41+
return #this;
42+
}
43+
static extension-type-member method Foo|constructor#_#tester1#tearOff(core::String s) → self::Foo% /* erasure=core::int, declared=! */
44+
return self::Foo|constructor#tester1(s);
45+
static extension-type-member method Foo|constructor#tester2(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
46+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
47+
return #this;
48+
}
49+
static extension-type-member method Foo|constructor#_#tester2#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
50+
return self::Foo|constructor#tester2(foo);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:3: Error: 'Foo' is already declared in this scope.
6+
// Foo([foo = foo]) => 42;
7+
// ^^^
8+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:5:19: Context: Previous declaration of 'Foo'.
9+
// extension type Foo(int foo) {
10+
// ^
11+
//
12+
import self as self;
13+
import "dart:core" as core;
14+
15+
extension type Foo(core::int foo) {
16+
abstract extension-type-member representation-field get foo() → core::int;
17+
constructor • = self::Foo|constructor#;
18+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
19+
constructor tester1 = self::Foo|constructor#tester1;
20+
constructor tearoff tester1 = self::Foo|constructor#_#tester1#tearOff;
21+
constructor tester2 = self::Foo|constructor#tester2;
22+
constructor tearoff tester2 = self::Foo|constructor#_#tester2#tearOff;
23+
}
24+
static extension-type-member method Foo|constructor#(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
25+
;
26+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
27+
return self::Foo|constructor#(foo);
28+
static extension-type-member method Foo|constructor#tester1(core::String s) → self::Foo% /* erasure=core::int, declared=! */
29+
;
30+
static extension-type-member method Foo|constructor#_#tester1#tearOff(core::String s) → self::Foo% /* erasure=core::int, declared=! */
31+
return self::Foo|constructor#tester1(s);
32+
static extension-type-member method Foo|constructor#tester2(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
33+
;
34+
static extension-type-member method Foo|constructor#_#tester2#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
35+
return self::Foo|constructor#tester2(foo);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:3: Error: 'Foo' is already declared in this scope.
6+
// Foo([foo = foo]) => 42;
7+
// ^^^
8+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:5:19: Context: Previous declaration of 'Foo'.
9+
// extension type Foo(int foo) {
10+
// ^
11+
//
12+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:14: Error: Not a constant expression.
13+
// Foo([foo = foo]) => 42;
14+
// ^^^
15+
//
16+
// pkg/front_end/testcases/regress/invalid_this_reference_06.dart:6:23: Error: Constructors can't have a return type.
17+
// Try removing the return type.
18+
// Foo([foo = foo]) => 42;
19+
// ^
20+
//
21+
import self as self;
22+
import "dart:core" as core;
23+
24+
extension type Foo(core::int foo) {
25+
abstract extension-type-member representation-field get foo() → core::int;
26+
constructor • = self::Foo|constructor#;
27+
constructor tearoff • = self::Foo|constructor#_#new#tearOff;
28+
constructor tester1 = self::Foo|constructor#tester1;
29+
constructor tearoff tester1 = self::Foo|constructor#_#tester1#tearOff;
30+
constructor tester2 = self::Foo|constructor#tester2;
31+
constructor tearoff tester2 = self::Foo|constructor#_#tester2#tearOff;
32+
}
33+
static extension-type-member method Foo|constructor#(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
34+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
35+
return #this;
36+
}
37+
static extension-type-member method Foo|constructor#_#new#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
38+
return self::Foo|constructor#(foo);
39+
static extension-type-member method Foo|constructor#tester1(core::String s) → self::Foo% /* erasure=core::int, declared=! */ {
40+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = s.{core::String::length}{core::int};
41+
return #this;
42+
}
43+
static extension-type-member method Foo|constructor#_#tester1#tearOff(core::String s) → self::Foo% /* erasure=core::int, declared=! */
44+
return self::Foo|constructor#tester1(s);
45+
static extension-type-member method Foo|constructor#tester2(core::int foo) → self::Foo% /* erasure=core::int, declared=! */ {
46+
lowered final self::Foo% /* erasure=core::int, declared=! */ #this = foo;
47+
return #this;
48+
}
49+
static extension-type-member method Foo|constructor#_#tester2#tearOff(core::int foo) → self::Foo% /* erasure=core::int, declared=! */
50+
return self::Foo|constructor#tester2(foo);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension type Foo(int foo) {
2+
Foo([foo = foo]) => 42;
3+
Foo.tester1(String s) : foo = s.length;
4+
Foo.tester2(this.foo);
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension type Foo(int foo) {
2+
Foo([foo = foo]) => 42;
3+
Foo.tester1(String s) : foo = s.length;
4+
Foo.tester2(this.foo);
5+
}

0 commit comments

Comments
 (0)