소스 검색

accept more ops as constant expression (closes #4819)

Simon Krajewski 9 년 전
부모
커밋
4d2f05562b
2개의 변경된 파일35개의 추가작업 그리고 1개의 파일을 삭제
  1. 4 1
      optimizer.ml
  2. 31 0
      tests/unit/src/unit/issues/Issue4819.hx

+ 4 - 1
optimizer.ml

@@ -1307,11 +1307,14 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 	let e = reduce_loop ctx e in
 	match e.eexpr with
 	| TConst _ -> Some e
-	| TBinop ((OpAdd|OpSub|OpMult|OpDiv|OpMod) as op,e1,e2) -> (match make_constant_expression ctx e1,make_constant_expression ctx e2 with
+	| TBinop ((OpAdd|OpSub|OpMult|OpDiv|OpMod|OpShl|OpShr|OpUShr|OpOr|OpAnd|OpXor) as op,e1,e2) -> (match make_constant_expression ctx e1,make_constant_expression ctx e2 with
 		| Some ({eexpr = TConst (TString s1)}), Some ({eexpr = TConst (TString s2)}) when concat_strings ->
 			Some (mk (TConst (TString (s1 ^ s2))) ctx.com.basic.tstring (punion e1.epos e2.epos))
 		| Some e1, Some e2 -> Some (mk (TBinop(op, e1, e2)) e.etype e.epos)
 		| _ -> None)
+	| TUnop((Neg | NegBits) as op,Prefix,e1) -> (match make_constant_expression ctx e1 with
+		| Some e1 -> Some (mk (TUnop(op,Prefix,e1)) e.etype e.epos)
+		| None -> None)
 	| TCast (e1, None) ->
 		(match make_constant_expression ctx e1 with
 		| None -> None

+ 31 - 0
tests/unit/src/unit/issues/Issue4819.hx

@@ -0,0 +1,31 @@
+package unit.issues;
+
+@:enum
+private abstract Enum1(Int) from Int to Int {
+	var AA = 16;
+}
+
+@:enum
+private abstract Enum2(Int) from Int to Int {
+	var BShl = Enum1.AA << 1;
+	var BShr = Enum1.AA >> 1;
+	var BUShr = Enum1.AA >>> 1;
+	var BOr = Enum1.AA | 1;
+	var BAnd = Enum1.AA & 1;
+	var BXor = Enum1.AA ^ 1;
+	var BNeg = -Enum1.AA;
+	var BNegBits = ~Enum1.AA;
+}
+
+class Issue4819 extends Test {
+	function test() {
+		eq(32, BShl);
+		eq(8, BShr);
+		eq(8, BUShr);
+		eq(17, BOr);
+		eq(0, BAnd);
+		eq(17, BXor);
+		eq(-16, BNeg);
+		eq(-17, BNegBits);
+	}
+}