浏览代码

[hlc] Fix SMOD/SDIV overflow exception when INT_MIN / -1 (#11917)

* [hlc] Fix SMOD/SDIV overflow exception when INT_MIN / -1

* [tests] skip div/mod 0 for other targets

* [tests] set to hl only
Yuxiao Mao 7 月之前
父节点
当前提交
8283e9bd5e
共有 2 个文件被更改,包括 17 次插入2 次删除
  1. 2 2
      src/generators/hl2c.ml
  2. 15 0
      tests/unit/src/unitstd/haxe/Int32.unit.hx

+ 2 - 2
src/generators/hl2c.ml

@@ -825,7 +825,7 @@ let generate_function ctx f =
 		| OSDiv (r,a,b) ->
 			(match rtype r with
 			| HUI8 | HUI16 | HI32 ->
-				sexpr "%s = %s == 0 ? 0 : %s / %s" (reg r) (reg b) (reg a) (reg b)
+				sexpr "%s = (%s == 0 || %s == -1) ? %s * %s : %s / %s" (reg r) (reg b) (reg b) (reg a) (reg b) (reg a) (reg b)
 			| _ ->
 				sexpr "%s = %s / %s" (reg r) (reg a) (reg b))
 		| OUDiv (r,a,b) ->
@@ -833,7 +833,7 @@ let generate_function ctx f =
 		| OSMod (r,a,b) ->
 			(match rtype r with
 			| HUI8 | HUI16 | HI32 | HI64 ->
-				sexpr "%s = %s == 0 ? 0 : %s %% %s" (reg r) (reg b) (reg a) (reg b)
+				sexpr "%s = (%s == 0 || %s == -1) ? 0 : %s %% %s" (reg r) (reg b) (reg b) (reg a) (reg b)
 			| HF32 ->
 				sexpr "%s = fmodf(%s,%s)" (reg r) (reg a) (reg b)
 			| HF64 ->

+ 15 - 0
tests/unit/src/unitstd/haxe/Int32.unit.hx

@@ -49,3 +49,18 @@ c == 0xfffffffe;
 -min == min;              // two's complement overflow,
 -2147483643 == 5 + -min;  // order of ops and negate
 2147483643 == -(5 + min); // static analyzer issue
+
+#if hl
+0 == min % 0;              // % 0 div by zero exception
+0 == Std.int(min / 0);
+0 == min % -1;             // min % -1 integer overflow exception
+min == Std.int(min / -1);
+min == min * -1;
+0 == min % 1;
+0 == max % 0;
+0 == Std.int(max / 0);
+0 == max % -1;
+-max == Std.int(max / -1);
+-max == max * -1;
+0 == max % 1;
+#end