dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.11k stars 1.57k forks source link

Incorrectly eliminated cast on numeric type in generic method #35618

Open munificent opened 5 years ago

munificent commented 5 years ago

If I run this program:

T sum<T extends num>(T value) {
  return 0 as T;
}

void main() {
  double d;
  print(sum(d));
  print(sum(d).isNaN);
}

On the bleeding edge VM:

Dart VM version: 2.2.0-edge.13a689f0fdb8de75f64db488d361edadae578d12 (Tue Jan 8 23:56:23 2019 +0000) on "macos_x64"

I get:

0
Unhandled exception:
type 'int' is not a subtype of type 'double' in type cast
#0      sum (file:///Users/rnystrom/temp/temp.dart:2:12)
#1      main (file:///Users/rnystrom/temp/temp.dart:8:9)
#2      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:289:19)
#3      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)

Note the first zero. The first call to sum() succeeds even though that cast should certainly fail. Interestingly, the call to isNaN apparently causes the cast inside the body of the function to be performed. I'm assuming some optimization pass is incorrectly eliminating the cast in the first call.

mraleph commented 5 years ago

This is a CFE bug:

 library from "file:///tmp/x.dart" as x {
   static method sum<T extends core::num = core::num>(x::sum::T value) → x::sum::T {
     return 0 as x::sum::T;
   }
   static method main() → void {
     core::double d;
     core::print(x::sum<core::num>(d));
     core::print(x::sum<core::double>(d).{core::num::isNaN});
   }
 }
munificent commented 5 years ago

Thanks, I wasn't sure where the in pipeline the bug happened, so I randomly picked "area-vm". :)