Skip to content

switch-case on String value uses incorrect value comparison in some cases #61098

@osa1

Description

@osa1

Originally reported in flutter/flutter#171803.

import 'dart:convert';
import 'dart:js_interop';
import 'dart:typed_data';


@JS()
external JSArrayBuffer readbuffer(String path);

Uint8List readfile(String path) {
  return Uint8List.fromList(readbuffer(path).toDart.asUint8List());
}

void main() {
  _option = utf8.decoder.convert(readfile("input")).trim();
  print(infoSwitchCase);
  print(infoSwitchCaseWithoutNull);
  print(infoSwitchExpression);
  print(infoIfCase);
  print(infoIfEquals);
}

const kTypeString = 'PhotographicBox';

String? _option;

String? get type => _option;

String get infoSwitchCase {
  switch (type) {
    case kTypeString:
      return 'It Works! on SWITCH CASE';
    case null:
      return 'Type is null on SWITCH CASE';
    default:
      return 'Unexpected type on SWITCH CASE: $type | $kTypeString';
  }
}

String get infoSwitchCaseWithoutNull {
  switch (type) {
    case kTypeString:
      return 'It Works! on SWITCH CASE WITHOUT NULL ---';
    default:
      return 'Unexpected type on SWITCH CASE WITHOUT NULL: $type | $kTypeString';
  }
}

String get infoSwitchExpression {
  return switch (type) {
    kTypeString => 'It Works with SWITCH EXPRESSION',
    null => 'Type is null with SWITCH EXPRESSION',
    _ => 'Unexpected type with SWITCH EXPRESSION: $type | $kTypeString',
  };
}

String get infoIfCase {
  if (type case kTypeString) {
    return 'It Works with IF CASE';
  } else if (type case null) {
    return 'Type is null with IF CASE';
  } else {
    return 'Unexpected type with IF CASE: $type | $kTypeString';
  }
}

String get infoIfEquals {
  if (type == kTypeString) {
    return 'It Works with IF';
  } else if (type == null) {
    return 'Type is null with IF';
  } else {
    return 'Unexpected type with IF: $type | $kTypeString';
  }
}

Create a file named "input" with contents PhotographicBox. When run we see this:

Unexpected type on SWITCH CASE: PhotographicBox | PhotographicBox
It Works! on SWITCH CASE WITHOUT NULL ---
It Works with SWITCH EXPRESSION
It Works with IF CASE
It Works with IF

In infoSwitchCase the string value matches the string constant in the case the branch isn't taken.

Looking at the Wasm code, in infoSwitchCase we somehow compare the string with identical instead of JSStringImpl.==. In other functions we use JSStringImpl.== as expected.

Note that the string needs to be fully dynamic for this bug to repro: I'm unable to repro it with tricks like _option = int.parse('1') == 1 ? "PhotographicBox" : "blah". That's why we have a file read in the repro.

Metadata

Metadata

Assignees

Labels

area-dart2wasmIssues for the dart2wasm compiler.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions