Răsfoiți Sursa

(Cpp) translate TWhile to TWhile(true) with a conditional TBreak to deal with side effects correctly (closes #2763)

Simon Krajewski 11 ani în urmă
părinte
comite
17844fd1be
3 a modificat fișierele cu 42 adăugiri și 0 ștergeri
  1. 1 0
      extra/CHANGES.txt
  2. 9 0
      filters.ml
  3. 32 0
      tests/unit/issues/Issue2763.hx

+ 1 - 0
extra/CHANGES.txt

@@ -4,6 +4,7 @@
 
 	all : properly disallowed usage of super as value
 	all : disallowed spaces between >>, >>>, >>= and >>>=
+	cpp : fixed bug in side-effect handler which caused incorrect behavior of while loops
 
 	General improvements and optimizations:
 

+ 9 - 0
filters.ml

@@ -106,6 +106,15 @@ let handle_side_effects com gen_temp e =
 				| _ ->
 					assert false
 			end
+		| TWhile(e1,e2,flag) when (match e1.eexpr with TParenthesis {eexpr = TConst(TBool true)} -> false | _ -> true) ->
+			let p = e.epos in
+			let e_break = mk TBreak t_dynamic p in
+			let e_not = mk (TUnop(Not,Prefix,Codegen.mk_parent e1)) e1.etype e1.epos in
+			let e_if = mk (TIf(e_not,e_break,None)) com.basic.tvoid p in
+			let e_block = if flag = NormalWhile then Codegen.concat e_if e2 else Codegen.concat e2 e_if in
+			let e_true = mk (TConst (TBool true)) com.basic.tbool p in
+			let e = mk (TWhile(Codegen.mk_parent e_true,e_block,NormalWhile)) e.etype p in
+			loop e
 		| _ ->
 			Type.map_expr loop e
 	and ordered_list el =

+ 32 - 0
tests/unit/issues/Issue2763.hx

@@ -0,0 +1,32 @@
+package unit.issues;
+import unit.Test;
+
+class Issue2763 extends Test {
+	function test() {
+		var i = 0;
+		var acc = "";
+		while (call(i++) < call2(i++)) {
+			acc += ";" + i;
+		}
+		eq(";2;4", acc);
+
+		var acc = "";
+		var i = 0;
+		do {
+			acc += ";" + i;
+		} while (call(i++) < call2(i++));
+		eq(";0;2;4", acc);
+    }
+
+	static function call(i:Int) {
+		return i;
+	}
+
+	static function call2(i:Int) {
+		if (i > 4) {
+			return -1;
+		} else {
+			return i;
+		}
+	}
+}