Skip to content

Analyzer incorrectly classifies certain for-in loops as dead code. #60424

@stereotype441

Description

@stereotype441

This code is erroneously accepted by the analyzer:

set v(Never value) {}
test(Object? x) {
  if (x is! int) {
    for (v in []) {}
  }
  print(x + 1);
}

The reason the analyzer is accepting the code is because the first step it takes in analyzing for (v in []) {}, is to resolve the simple identifier v (this resolves to the setter v), then it takes the type of the setter (Never) and stores it into the AST node for v using ExpressionImpl.recordStaticType. A side effect of ExpressionImpl.recordStaticType is to mark the control flow path as unreachable if the type if Never. Therefore, it considers the "then" branch of the "if" statement to be dead code, and so it considers the "if" statement to promote x to int.

This is incorrect. The actual behavior of for (v in []) is a no-op, since the iterable expression is empty; therefore both branches of the "if" statement are live, and so it is not sound to promote x.

If you try to run this code using the front end, it correctly rejects it:

test.dart:6:11: Error: The operator '+' isn't defined for the class 'Object?'.
 - 'Object' is from 'dart:core'.
Try correcting the operator to an existing operator, or defining a '+' operator.
  print(x + 1);
          ^

Since it's hard to imagine this problem cropping up in real-world code, I'm inclined to classify it as a P3. However, it's a soundness bug, which we typically classify as fairly high priority. So I'm going to compromise and call it a P2.

Metadata

Metadata

Assignees

Labels

P2A bug or feature request we're likely to work onarea-dart-modelFor issues related to conformance to the language spec in the parser, compilers or the CLI analyzer.dart-model-analyzer-specIssues with the analyzer's implementation of the language specmodel-flowImplementation of flow analysis in analyzer/cfesoundness

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions