thx.core
thx.core copied to clipboard
[HXCPP][XCODE16.0] thx.bigint.Bigs.canAdd(2000000000, 400000000); returns true wrongly.
Source code is:
public static function canAdd(a : Int, b : Int) {
var v = a + b;
if (a > 0 && b > 0 && v < 0)
return false;
return isPrecise(v);
}
The generated cpp code is:
HXCPP_OPTIMIZATION_HINT_METHOD bool Bigs_obj::canAdd(int a,int b){
HX_STACKFRAME(&_hx_pos_0c9c58070269a9c2_49_canAdd)
HXLINE( 50) int v = (a + b);
HXLINE( 51) bool _hx_tmp;
HXDLIN( 51) bool _hx_tmp1;
HXDLIN( 51) if ((a > 0)) {
HXLINE( 51) _hx_tmp1 = (b > 0);
}
else {
HXLINE( 51) _hx_tmp1 = false;
}
HXDLIN( 51) if (_hx_tmp1) {
HXLINE( 51) _hx_tmp = (v < 0);
}
else {
HXLINE( 51) _hx_tmp = false;
}
HXDLIN( 51) if (_hx_tmp) {
HXLINE( 52) return false;
}
HXLINE( 53) return ::thx::bigint::Bigs_obj::isPrecise(v);
}
where HXCPP_OPTIMIZATION_HINT_METHOD is __attribute__((minsize))
assembly code:
thx::bigint::Bigs_obj::canAdd:
0x10872ac04 <+0>: sub sp, sp, #0x40
0x10872ac08 <+4>: stp x20, x19, [sp, #0x20]
0x10872ac0c <+8>: stp x29, x30, [sp, #0x30]
0x10872ac10 <+12>: add x29, sp, #0x30
0x10872ac14 <+16>: mov x19, x1
0x10872ac18 <+20>: mov x20, x0
0x10872ac1c <+24>: adrp x1, 7446
0x10872ac20 <+28>: add x1, x1, #0x8b0 ; FBLink_UIPasteboard_FBSDKPasteboard + 3572664
0x10872ac24 <+32>: bl 0x107dcaacc ; _OUTLINED_FUNCTION_5
0x10872ac28 <+36>: add w0, w19, w20
-> 0x10872ac2c <+40>: mov w8, #0x35 ; =53
0x10872ac30 <+44>: str w8, [sp, #0x18]
0x10872ac34 <+48>: bl 0x10872a78c ; thx::bigint::Bigs_obj::isPrecise at Bigs.cpp:136
0x10872ac38 <+52>: mov x19, x0
0x10872ac3c <+56>: bl 0x107dcaa84 ; _OUTLINED_FUNCTION_1
0x10872ac40 <+60>: mov x0, x19
0x10872ac44 <+64>: ldp x29, x30, [sp, #0x30]
0x10872ac48 <+68>: b 0x107dcaadc ; _OUTLINED_FUNCTION_7
0x10872ac4c <+72>: mov x19, x0
0x10872ac50 <+76>: bl 0x107dcaa84 ; _OUTLINED_FUNCTION_1
0x10872ac54 <+80>: bl 0x107dcaad4 ; _OUTLINED_FUNCTION_6
My guess is that Xcode compiler considers (a > 0 && b > 0 && v < 0) without overflow and optimizes it away. My mitigation is to use Int64 check overflow:
public static function canAdd(a : Int, b : Int) {
if (a > 0 && b > 0 && haxe.Int64.ofInt(a) + haxe.Int64.ofInt(b) > haxe.Int64.ofInt(2147483647))
return false;
return isPrecise(a + b);
}
Please provide a PR and I will gladly merge ;)