Skip to content

Wrong flow analysis after non-nulable type and ==null #60114

@sgrekhov

Description

@sgrekhov

The following code works well and produces no errors in both CFE and the analyzer.

main() {
  late int i;
  String s = "";
  if (s == null) {  // Warning: unnecessary_null_comparison
    i = 42;
  }
  i; // No error
}

But according to the flow analysis specification:

operator== If N is an expression of the form E1 == E2, where the static type of E1 is T1 and the static type of E2 is T2, then:
...

  • Otherwise, if equivalentToNull(T1) and T2 is non-nullable, or equivalentToNull(T2) and T1 is non-nullable, then:
    • Let true(N) = unreachable(after(E2)).
    • Let false(N) = after(E2).

According to the above, the body of if (s == null) ... is unreachable and therefore initialization of i occurs in a dead code. This leaves i definitely unassigned and therefore i; should be a compile-time error.

Probably this happens because s == null is not always false in an unsound mode, but there are no mentions of unsound mode in the flow analysis spec.

cc @johnniwinther

Dart SDK version: 3.8.0-73.0.dev (dev) (Thu Feb 6 20:02:31 2025 -0800) on "windows_x64"

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.model-flowImplementation of flow analysis in analyzer/cfetype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions