Skip to content

Commit

Permalink
[beta] [tfa] Fix crash when building field guard summary with capture…
Browse files Browse the repository at this point in the history
…d receiver

When building a field guard summary, field initializer is not included
into the body. So field initializer AST should not be visited to
calculate captured variables and field guard summary
should not have a captured reveiver.

TEST=pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter147239.dart

Issue: flutter/flutter#147239
Change-Id: Ibb4827edcfb253c13ac40e6167a447ad36d9eb5e
Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/364203
Cherry-pick-request: #55557
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/364380
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
  • Loading branch information
alexmarkov authored and Commit Queue committed Apr 26, 2024
1 parent c11d54e commit a8df3c4
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
9 changes: 5 additions & 4 deletions pkg/vm/lib/transformations/type_flow/summary_collector.dart
Expand Up @@ -302,9 +302,7 @@ class _VariablesInfoCollector extends RecursiveVisitor {
LocalFunction? summaryFunction;
int numVariablesAtSummaryFunctionEntry = 0;

_VariablesInfoCollector(Member member, this.summaryFunction) {
member.accept(this);
}
_VariablesInfoCollector(this.summaryFunction);

int get numVariables => varDeclarations.length;

Expand Down Expand Up @@ -638,7 +636,10 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
}

_staticTypeContext = StaticTypeContext(member, _environment);
_variablesInfo = _VariablesInfoCollector(member, localFunction);
_variablesInfo = _VariablesInfoCollector(localFunction);
if (fieldSummaryType != FieldSummaryType.kFieldGuard) {
member.accept(_variablesInfo);
}
_variableValues = List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
_aggregateVariable = List<bool>.filled(_variablesInfo.numVariables, false);
_capturedVariableReads = null;
Expand Down
@@ -0,0 +1,17 @@
// 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.

// Regression test for https://github.com/flutter/flutter/issues/147239.
// Verifies that TFA doesn't crash when creating a field guard summary
// for a field which has initializer with closure and captured receiver.

class Foo<T> {
late final aField = () {
return <T>[];
};
}

main() {
print(Foo<String>().aField);
}
@@ -0,0 +1,19 @@
library #lib;
import self as self;
import "dart:core" as core;

class Foo<T extends core::Object? = dynamic> extends core::Object {

[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::Foo.aField)]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
[@vm.closure-id=1]
late covariant-by-class final field () → core::List<self::Foo::T%> aField = [@vm.closure-id=1]() → core::List<self::Foo::T%> {
return [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::String>] core::_GrowableList::•<self::Foo::T%>(0);
};
synthetic constructor •() → self::Foo<self::Foo::T%>
: super core::Object::•()
;
}
static method main() → dynamic {
core::print([@vm.direct-call.metadata=#lib::Foo.aField] [@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::Foo.aField)] new self::Foo::•<core::String>().{self::Foo::aField}{() → core::List<core::String>});
}

0 comments on commit a8df3c4

Please sign in to comment.