From 166e46575f0f606f6263ce001a9be2fa1822599f Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Wed, 17 Apr 2024 08:48:11 +0000 Subject: [PATCH] [CFE] Fix leak via extension types Found via the weekly bot. Change-Id: Id5b7890db4d4c0e1dfca4160c99ceb0c7dbfaafe Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363040 Reviewed-by: Johnni Winther Commit-Queue: Jens Johansen --- .../kernel/hierarchy/members_builder.dart | 1 + .../testcases/incremental/extension_type.yaml | 25 +++++++++++++++++++ .../extension_type.yaml.world.1.expect | 18 +++++++++++++ .../extension_type.yaml.world.2.expect | 18 +++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 pkg/front_end/testcases/incremental/extension_type.yaml create mode 100644 pkg/front_end/testcases/incremental/extension_type.yaml.world.1.expect create mode 100644 pkg/front_end/testcases/incremental/extension_type.yaml.world.2.expect diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart index 13aac2c0381..0fc144c17b5 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart @@ -39,6 +39,7 @@ class ClassMembersBuilder implements ClassHierarchyMembers { _delayedChecks.clear(); _delayedTypeComputations.clear(); _delayedMemberComputations.clear(); + extensionTypeDeclarationNodes.clear(); } void registerDelayedTypeComputation(DelayedTypeComputation computation) { diff --git a/pkg/front_end/testcases/incremental/extension_type.yaml b/pkg/front_end/testcases/incremental/extension_type.yaml new file mode 100644 index 00000000000..64bdfc01ce0 --- /dev/null +++ b/pkg/front_end/testcases/incremental/extension_type.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2024, 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. + +# Reproduce a leak. + +type: newworld +worlds: + - entry: main.dart + noFullComponent: true + sources: + main.dart: | + extension type const _Foo._(int _foo) { + _Foo operator +(_Foo other) => throw "hello"; + } + expectedLibraryCount: 1 + + - entry: main.dart + worldType: updated + expectInitializeFromDill: false + noFullComponent: true + invalidate: + - main.dart + expectedLibraryCount: 1 + advancedInvalidation: bodiesOnly diff --git a/pkg/front_end/testcases/incremental/extension_type.yaml.world.1.expect b/pkg/front_end/testcases/incremental/extension_type.yaml.world.1.expect new file mode 100644 index 00000000000..37dafc9da9c --- /dev/null +++ b/pkg/front_end/testcases/incremental/extension_type.yaml.world.1.expect @@ -0,0 +1,18 @@ +main = ; +library from "org-dartlang-test:///main.dart" as main { + + extension type _Foo(dart.core::int _foo) { + abstract extension-type-member representation-field get _foo() → dart.core::int; + operator + = main::_Foo|+; + constructor _ = main::_Foo|constructor#_; + constructor tearoff _ = main::_Foo|constructor#_#_#tearOff; + } + static extension-type-member method _Foo|constructor#_(dart.core::int _foo) → main::_Foo% /* erasure=dart.core::int, declared=! */ { + lowered final main::_Foo% /* erasure=dart.core::int, declared=! */ #this = _foo; + return #this; + } + static extension-type-member method _Foo|constructor#_#_#tearOff(dart.core::int _foo) → main::_Foo% /* erasure=dart.core::int, declared=! */ + return main::_Foo|constructor#_(_foo); + static extension-type-member method _Foo|+(lowered final main::_Foo% /* erasure=dart.core::int, declared=! */ #this, main::_Foo% /* erasure=dart.core::int, declared=! */ other) → main::_Foo% /* erasure=dart.core::int, declared=! */ + return throw "hello"; +} diff --git a/pkg/front_end/testcases/incremental/extension_type.yaml.world.2.expect b/pkg/front_end/testcases/incremental/extension_type.yaml.world.2.expect new file mode 100644 index 00000000000..37dafc9da9c --- /dev/null +++ b/pkg/front_end/testcases/incremental/extension_type.yaml.world.2.expect @@ -0,0 +1,18 @@ +main = ; +library from "org-dartlang-test:///main.dart" as main { + + extension type _Foo(dart.core::int _foo) { + abstract extension-type-member representation-field get _foo() → dart.core::int; + operator + = main::_Foo|+; + constructor _ = main::_Foo|constructor#_; + constructor tearoff _ = main::_Foo|constructor#_#_#tearOff; + } + static extension-type-member method _Foo|constructor#_(dart.core::int _foo) → main::_Foo% /* erasure=dart.core::int, declared=! */ { + lowered final main::_Foo% /* erasure=dart.core::int, declared=! */ #this = _foo; + return #this; + } + static extension-type-member method _Foo|constructor#_#_#tearOff(dart.core::int _foo) → main::_Foo% /* erasure=dart.core::int, declared=! */ + return main::_Foo|constructor#_(_foo); + static extension-type-member method _Foo|+(lowered final main::_Foo% /* erasure=dart.core::int, declared=! */ #this, main::_Foo% /* erasure=dart.core::int, declared=! */ other) → main::_Foo% /* erasure=dart.core::int, declared=! */ + return throw "hello"; +}