Browse Source

Handle `1 - - 2` in santize_expr (#8318)

* unwrap untyped cast before optimizing binops & unops

* workaround `- cast -1` in `sanitize_expr`

* test Float too

* fix test for #6229

* don't optimize unops and binops for @:coreType abstracts

* give up

* revert test 6229

* fix test for cs & flash
Aleksandr Kuzmenko 6 years ago
parent
commit
1475878424
2 changed files with 54 additions and 0 deletions
  1. 12 0
      src/optimization/optimizer.ml
  2. 42 0
      tests/unit/src/unit/issues/Issue6942.hx

+ 12 - 0
src/optimization/optimizer.ml

@@ -118,6 +118,16 @@ let sanitize_expr com e =
 			| TBinop (op2,_,_) -> if left then not (swap op2 op) else swap op op2
 			| TIf _ -> if left then not (swap (OpAssignOp OpAssign) op) else swap op (OpAssignOp OpAssign)
 			| TCast (e,None) | TMeta (_,e) -> loop e left
+			| TConst (TInt i) when not left ->
+				(match op with
+					| OpAdd | OpSub -> (Int32.to_int i) < 0
+					| _ -> false
+				)
+			| TConst (TFloat flt) when not left ->
+				(match op with
+					| OpAdd | OpSub -> String.get flt 0 = '-'
+					| _ -> false
+				)
 			| _ -> false
 		in
 		let e1 = if loop e1 true then parent e1 else e1 in
@@ -126,6 +136,8 @@ let sanitize_expr com e =
 	| TUnop (op,mode,e1) ->
 		let rec loop ee =
 			match ee.eexpr with
+			| TConst (TInt i) when op = Neg && (Int32.to_int i) < 0 -> parent e1
+			| TConst (TFloat flt) when op = Neg && String.get flt 0 = '-' -> parent e1
 			| TBinop _ | TIf _ | TUnop _ -> parent e1
 			| TCast (e,None) | TMeta (_, e) -> loop e
 			| _ -> e1

+ 42 - 0
tests/unit/src/unit/issues/Issue6942.hx

@@ -0,0 +1,42 @@
+package unit.issues;
+
+class Issue6942 extends unit.Test {
+	static inline var FLOAT_INLINE = -1.0;
+	static inline var INT_INLINE = -1;
+
+	function test() {
+		eq(1, -IntEnum);
+		eq(2, 1 - IntEnum);
+
+		//these targets have actual UInt type at runtime
+		#if (flash || cs || as3)
+		eq(-4294967295, -UIntEnum);
+		eq(2, 1 - UIntEnum);
+		#else
+		eq(1, -UIntEnum);
+		eq(2, 1 - UIntEnum);
+		#end
+
+		eq(1, -INT_INLINE);
+		eq(2, 1 - INT_INLINE);
+
+		// TODO: fix https://github.com/HaxeFoundation/haxe/issues/8321
+		// eq(1.0, -FloatEnum);
+		// eq(2.0, 1 - FloatEnum);
+
+		eq(1.0, -FLOAT_INLINE);
+		eq(2.0, 1 - FLOAT_INLINE);
+	}
+}
+
+enum abstract FloatTest(Float) from Float to Float {
+	var FloatEnum = -1.0;
+}
+
+enum abstract IntTest(Int) from Int to Int {
+	var IntEnum = -1;
+}
+
+enum abstract UIntTest(UInt) from UInt to UInt {
+	var UIntEnum = -1;
+}