Skip to content

Commit bb5b37e

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Flow analysis is not available outside of function bodies and initializers.
This fixes a group of crashes during fuzz testing. FAILURE: typedef`(=<?[ [NoSuchMethodError: The method 'nullAwareAccess_rightBegin' was called on null. Receiver: null Tried calling: nullAwareAccess_rightBegin(Instance of 'ListLiteralImpl', Instance of 'InterfaceTypeImpl'), #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5) flutter#1 ResolverVisitor.startNullAwareIndexExpression (package:analyzer/src/generated/resolver.dart:776:26) flutter#2 ResolverVisitor.visitIndexExpression (package:analyzer/src/generated/resolver.dart:1585:5) flutter#3 IndexExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:5993:49) flutter#4 DefaultFormalParameterImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:3008:20) #5 ResolverVisitor.visitNode (package:analyzer/src/generated/resolver.dart:1743:10) flutter#6 UnifyingAstVisitor.visitDefaultFormalParameter (package:analyzer/dart/ast/visitor.dart:3198:65) flutter#7 ResolverVisitor.visitDefaultFormalParameter (package:analyzer/src/generated/resolver.dart:1239:11) flutter#8 DefaultFormalParameterImpl.accept (package:analyzer/src/dart/ast/ast.dart:3003:15) flutter#9 NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7611:20) flutter#10 FormalParameterListImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:4493:17) flutter#11 ResolverVisitor.visitNode (package:analyzer/src/generated/resolver.dart:1743:10) flutter#12 UnifyingAstVisitor.visitFormalParameterList (package:analyzer/dart/ast/visitor.dart:3258:59) flutter#13 ScopedVisitor.visitFormalParameterList (package:analyzer/src/generated/resolver.dart:2717:11) flutter#14 FormalParameterListImpl.accept (package:analyzer/src/dart/ast/ast.dart:4489:49) flutter#15 FunctionTypeAliasImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:5166:18) flutter#16 ResolverVisitor.visitNode (package:analyzer/src/generated/resolver.dart:1743:10) flutter#17 UnifyingAstVisitor.visitFunctionTypeAlias (package:analyzer/dart/ast/visitor.dart:3285:55) flutter#18 ScopedVisitor.visitFunctionTypeAliasInScope (package:analyzer/src/generated/resolver.dart:2819:11) flutter#19 ResolverVisitor.visitFunctionTypeAliasInScope (package:analyzer/src/generated/resolver.dart:1490:11) flutter#20 ScopedVisitor.visitFunctionTypeAlias (package:analyzer/src/generated/resolver.dart:2812:7) #21 ResolverVisitor.visitFunctionTypeAlias (package:analyzer/src/generated/resolver.dart:1482:13) #22 FunctionTypeAliasImpl.accept (package:analyzer/src/dart/ast/ast.dart:5158:49) #23 ResolverVisitor.visitCompilationUnit (package:analyzer/src/generated/resolver.dart:1088:23) #24 CompilationUnitImpl.accept (package:analyzer/src/dart/ast/ast.dart:2134:49) #25 LibraryAnalyzer._resolveFile (package:analyzer/src/dart/analysis/library_analyzer.dart:706:10) Continues //dart-review.googlesource.com/c/sdk/+/175187 Change-Id: I9518363961b4adcf7f57c2f0661151ef74efc2f5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175906 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 140afee commit bb5b37e

File tree

4 files changed

+70
-25
lines changed

4 files changed

+70
-25
lines changed

pkg/analyzer/lib/src/generated/resolver.dart

+31-25
Original file line numberDiff line numberDiff line change
@@ -771,26 +771,29 @@ class ResolverVisitor extends ScopedVisitor {
771771
}
772772

773773
void startNullAwareIndexExpression(IndexExpression node) {
774-
if (_migratableAstInfoProvider.isIndexExpressionNullAware(node) &&
775-
_flowAnalysis != null) {
776-
_flowAnalysis.flow.nullAwareAccess_rightBegin(
777-
node.target, node.realTarget.staticType ?? typeProvider.dynamicType);
778-
_unfinishedNullShorts.add(node.nullShortingTermination);
774+
if (_migratableAstInfoProvider.isIndexExpressionNullAware(node)) {
775+
var flow = _flowAnalysis?.flow;
776+
if (flow != null) {
777+
flow.nullAwareAccess_rightBegin(node.target,
778+
node.realTarget.staticType ?? typeProvider.dynamicType);
779+
_unfinishedNullShorts.add(node.nullShortingTermination);
780+
}
779781
}
780782
}
781783

782-
void startNullAwarePropertyAccess(
783-
PropertyAccess node,
784-
) {
785-
if (_migratableAstInfoProvider.isPropertyAccessNullAware(node) &&
786-
_flowAnalysis != null) {
787-
var target = node.target;
788-
if (target is SimpleIdentifier && target.staticElement is ClassElement) {
789-
// `?.` to access static methods is equivalent to `.`, so do nothing.
790-
} else {
791-
_flowAnalysis.flow.nullAwareAccess_rightBegin(
792-
target, node.realTarget.staticType ?? typeProvider.dynamicType);
793-
_unfinishedNullShorts.add(node.nullShortingTermination);
784+
void startNullAwarePropertyAccess(PropertyAccess node) {
785+
if (_migratableAstInfoProvider.isPropertyAccessNullAware(node)) {
786+
var flow = _flowAnalysis?.flow;
787+
if (flow != null) {
788+
var target = node.target;
789+
if (target is SimpleIdentifier &&
790+
target.staticElement is ClassElement) {
791+
// `?.` to access static methods is equivalent to `.`, so do nothing.
792+
} else {
793+
flow.nullAwareAccess_rightBegin(
794+
target, node.realTarget.staticType ?? typeProvider.dynamicType);
795+
_unfinishedNullShorts.add(node.nullShortingTermination);
796+
}
794797
}
795798
}
796799
}
@@ -1684,14 +1687,17 @@ class ResolverVisitor extends ScopedVisitor {
16841687
var target = node.target;
16851688
target?.accept(this);
16861689

1687-
if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
1688-
_flowAnalysis != null) {
1689-
if (target is SimpleIdentifier && target.staticElement is ClassElement) {
1690-
// `?.` to access static methods is equivalent to `.`, so do nothing.
1691-
} else {
1692-
_flowAnalysis.flow.nullAwareAccess_rightBegin(
1693-
target, node.realTarget.staticType ?? typeProvider.dynamicType);
1694-
_unfinishedNullShorts.add(node.nullShortingTermination);
1690+
if (_migratableAstInfoProvider.isMethodInvocationNullAware(node)) {
1691+
var flow = _flowAnalysis?.flow;
1692+
if (flow != null) {
1693+
if (target is SimpleIdentifier &&
1694+
target.staticElement is ClassElement) {
1695+
// `?.` to access static methods is equivalent to `.`, so do nothing.
1696+
} else {
1697+
flow.nullAwareAccess_rightBegin(
1698+
target, node.realTarget.staticType ?? typeProvider.dynamicType);
1699+
_unfinishedNullShorts.add(node.nullShortingTermination);
1700+
}
16951701
}
16961702
}
16971703

pkg/analyzer/test/src/dart/resolution/index_expression_test.dart

+13
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ void f({a = b?[0]}) {}
2929
);
3030
}
3131

32+
test_invalid_inDefaultValue_nullAware2() async {
33+
await assertInvalidTestCode(r'''
34+
typedef void F({a = b?[0]});
35+
''');
36+
37+
assertIndexExpression(
38+
findNode.index('[0]'),
39+
readElement: null,
40+
writeElement: null,
41+
type: 'dynamic',
42+
);
43+
}
44+
3245
test_read() async {
3346
await assertNoErrorsInCode(r'''
3447
class A {

pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart

+14
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,20 @@ void f({a = b?.foo()}) {}
17181718
);
17191719
}
17201720

1721+
test_invalid_inDefaultValue_nullAware2() async {
1722+
await assertInvalidTestCode('''
1723+
typedef void F({a = b?.foo()});
1724+
''');
1725+
1726+
assertMethodInvocation2(
1727+
findNode.methodInvocation('?.foo()'),
1728+
element: null,
1729+
typeArgumentTypes: [],
1730+
invokeType: 'dynamic',
1731+
type: 'dynamic',
1732+
);
1733+
}
1734+
17211735
test_namedArgument() async {
17221736
var question = typeToStringWithNullability ? '?' : '';
17231737
await assertNoErrorsInCode('''

pkg/analyzer/test/src/dart/resolution/property_access_test.dart

+12
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,18 @@ void f({a = b?.foo}) {}
250250
);
251251
}
252252

253+
test_invalid_inDefaultValue_nullAware2() async {
254+
await assertInvalidTestCode('''
255+
typedef void F({a = b?.foo});
256+
''');
257+
258+
assertPropertyAccess2(
259+
findNode.propertyAccess('?.foo'),
260+
element: null,
261+
type: 'dynamic',
262+
);
263+
}
264+
253265
test_invalid_inDefaultValue_nullAware_cascade() async {
254266
await assertInvalidTestCode('''
255267
void f({a = b?..foo}) {}

0 commit comments

Comments
 (0)