Null exception when casting with inheritance of depth 2+
Casting a subclass of a subclass to their base class will cause a strange "null" exception at line 0 of a random external/standard library.
abstract class A {
public abstract function work():Void;
}
abstract class B extends A {
public abstract function work(): Void;
}
class C extends B {
public function new() {}
public function work():Void {
trace("doing");
}
}
class Main {
static function main(){
var c = new C();
var a: A = cast c;
a.work();
}
}
Result:
Called from A.work(C:\HaxeToolkit\haxe\std/hl/_std/Date.hx:0) Called from $Main.main(Main.hx:24) Called from .init(?:1)
As you can see it strangely fails at "Date.hx:0". Casting to Dynamic instead can be used as a workaround.
The above code snippet works in other targets.
This comes from haxe compiler (genhl) that does not detect that the abstract "work" method is overriden in subclasses, and thus creates a static call to A.work() instead of dynamic call for the specific instance.
Here's ASM dump:
.21 @0 new 0
.21 @1 call 1, C.new(0)
.23 @2 call 1, A.work(0)
.24 @3 ret 1
The temporary solution is to either define the work() method in A (not abstract method) or maybe to override it in a class D extends C, but I don't think that will be enough.