Files
sdk/tests/language/patterns/flow_analysis/pattern_assignment_lookahead_test.dart
T
Paul Berry 2ca7380ab0 Flow analysis: fix first phase handling of pattern assignments.
Prior to this change, the first phase of flow analysis, in which flow
analysis "looks ahead" to see which variables are potentially assigned
in each code block, was failing to properly account for variables that
are assigned by pattern assignment expressions. This "look ahead"
information is used by flow analysis to determine the effects of
nonlinear control flow (e.g. to figure out which variables to demote
at the top of a loop, or to figure out which variables are potentially
assigned inside a closure). As a result, it was possible to construct
correct code that would be rejected by the analyzer and compiler, as
well as incorrect code that would (unsoundly) be accepted.

The fix is to call `AssignedVariables.write` from the analyzer's
`FlowAnalysisVisitor`, and from the CFE's `BodyBuilder`, to let flow
analysis know about variable assignments that occur inside pattern
assignment expressions.

Fixes #52745.

Change-Id: I0e6f426a5c5c36f214d5a206aaf5a2de0bfdaac1
Bug: https://github.com/dart-lang/sdk/issues/52745
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310502
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2023-06-21 14:33:42 +00:00

24 lines
1.0 KiB
Dart

// Copyright (c) 2023, 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.
// Verifies that the first phase of flow analysis (used for "lookahead" to see
// what variables are assigned inside loops and closures) properly detects
// variables assigned inside pattern assignments.
void main() {
late String s;
// `s` is definitely unassigned at this point.
() {
(s,) = ('',);
}();
// `s` should be considered potentially assigned at this point, since there's
// an assignment to it inside the closure. (In point of fact, it's definitely
// assigned, because the closure has definitely been called at this point, and
// all control paths through the closure definitely assign to `s`. But flow
// analysis only tracks closure creation, not calls to closures, so all it
// knows is that `s` is potentially assigned). Therefore it should be legal to
// read from `s` now.
print(s);
}