Skip to content

Unsound treatment of label: break label; in type/flow analysis #50294

Closed
@lrhn

Description

@lrhn

Take some ridiculous code like:

void main() {
  int x = foo();
  print(x.runtimeType);
}

int foo() {
  num x = 1.5;
  if (x is! int) {
    label: break label;
    print("Gotcha");
  }
  return x;
}

This code compiles and prints Gotcha and double.

If I change label: break label; to the supposedly completely equivalent label: { break label; }, it stops compiling, because the flow analysis correctly deduces that label: { break label; } can terminate normally.

The label: break label; is mistakenly seen as not terminating. Code immediately after it is considered dead code by the analyzer. Type promotion assumes it never completes.

This affects both analyzer and front-end.

(Guessing we are doing something special with lables, maybe storing them on the inner statement's AST node instead of making a labeled statement a proper composite statement with its own AST node, which makes it much easier to forget that they can be on any statement. Especially since it only matters for composite statements which can contain a break or continue. Which includes break statements.)

(Found while looking at dart-lang/language#2586).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2A bug or feature request we're likely to work ondart-model-analyzer-specIssues with the analyzer's implementation of the language speclegacy-area-analyzerUse area-devexp instead.legacy-area-front-endLegacy: Use area-dart-model instead.soundnesstype-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