Skip to content

How do we handle flow analysis of dead code? #4287

Open
@eernstg

Description

@eernstg

Thanks to @sgrekhov for bringing up this topic! Consider the following situation:

void f(Never n) {
  final _ = n ? 1 : 2;
  print('Unreachable!');
}

The analyzer accepts this code without any diagnostic messages (Dart SDK 3.8.0-149.0.dev and Flutter SDK 3.30.0-1.0.pre.470).

However, the evaluation of n in the condition of the conditional expression is specified (in the 'variable or getter' case) to make subsequent code unreachable.

We do get 'dead code' warnings in the following case:

void g(Never n) {
  final _ = (throw 0) ? 1 : 2; // Warning on `1` and on `2`.
  print('Unreachable!'); // Warning.
}

The analysis is somewhat tainted by the fact that the entire body of f is dead code (because an invocation could never proceed unless n were bound to an object whose run-time type is Never, and that will never happen, pun intended). This means that any assumption about the properties of the code is sound (we will never need to deliver on those promises).

So how do we manage this freedom to assume arbitrary things? We could determine that a certain amount of code is dead, and then omit any further analysis (because it doesn't make sense anyway, at least not always).

We could also proceed to analyze the dead code relying on conclusions that do not depend on the flow analysis (so we won't assume that any variables have been promoted before the dead code starts running, but we do recognize that code after throw 0 is unreachable, no matter what the control flow has been so far).

The remaining funny quirk is that the evaluation of n in f doesn't count as an event that makes subsequent code unreachable, perhaps because the flow analysis assumes that "we can always evaluate a formal parameter, and it doesn't throw!".

This raises a couple of questions:

  • Do we simply have a bug in the treatment of formal parameters of a type T <: Never? Or is it intentional that we treat them as "safely readable, even if the type is Never"?
  • Can we perform a static analysis on dead code that disregards all information from flow analysis? Or can we include some flow analysis information without producing absurd results? Should we?

@stereotype441, WDYT?

Metadata

Metadata

Assignees

No one assigned

    Labels

    flow-analysisDiscussions about possible future improvements to flow analysisquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions