Browse Source

[analyzer] properly deal with TArray in fusion

closes #6776
Simon Krajewski 7 years ago
parent
commit
a8d91a4f94
2 changed files with 40 additions and 11 deletions
  1. 21 11
      src/optimization/analyzerTexpr.ml
  2. 19 0
      tests/unit/src/unit/issues/Issue6776.hx

+ 21 - 11
src/optimization/analyzerTexpr.ml

@@ -878,6 +878,27 @@ module Fusion = struct
 						| TUnop((Increment | Decrement),_,{eexpr = TField(e1,fa)}) when has_field_read ir (field_name fa) || has_state_read ir
 						| TUnop((Increment | Decrement),_,{eexpr = TField(e1,fa)}) when has_field_read ir (field_name fa) || has_state_read ir
 							|| has_field_write ir (field_name fa) || has_state_write ir ->
 							|| has_field_write ir (field_name fa) || has_state_write ir ->
 							raise Exit
 							raise Exit
+						(* array *)
+						| TArray(e1,e2) ->
+							let e1 = replace e1 in
+							let e2 = replace e2 in
+							if not !found && has_state_write ir then raise Exit;
+							{e with eexpr = TArray(e1,e2)}
+						| TBinop(OpAssign,({eexpr = TArray(e1,e2)} as ef),e3) ->
+							let e1 = replace e1 in
+							let e2 = replace e2 in
+							let e3 = replace e3 in
+							if not !found && (has_state_read ir) then raise Exit;
+							{e with eexpr = TBinop(OpAssign,{ef with eexpr = TArray(e1,e2)},e3)}
+						| TBinop(OpAssignOp _ as op,({eexpr = TArray(e1,e2)} as ef),e3) ->
+							let e1 = replace e1 in
+							let e2 = replace e2 in
+							if not !found && has_state_write ir then raise Exit;
+							let e3 = replace e3 in
+							if not !found && has_state_read ir then raise Exit;
+							{e with eexpr = TBinop(op,{ef with eexpr = TArray(e1,e2)},e3)}
+						| TUnop((Increment | Decrement),_,{eexpr = TArray _}) when has_state_read ir || has_state_write ir ->
+							raise Exit
 						(* state *)
 						(* state *)
 						| TCall({eexpr = TIdent s},el) when not (is_unbound_call_that_might_have_side_effects s el) ->
 						| TCall({eexpr = TIdent s},el) when not (is_unbound_call_that_might_have_side_effects s el) ->
 							e
 							e
@@ -911,12 +932,6 @@ module Fusion = struct
 							let el = handle_el el in
 							let el = handle_el el in
 							(*if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit;*)
 							(*if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit;*)
 							{e with eexpr = TArrayDecl el}
 							{e with eexpr = TArrayDecl el}
-						| TBinop(OpAssign,({eexpr = TArray(e1,e2)} as ea),e3) ->
-							let e1 = replace e1 in
-							let e2 = replace e2 in
-							let e3 = replace e3 in
-							if not !found && has_state_read ir then raise Exit;
-							{e with eexpr = TBinop(OpAssign,{ea with eexpr = TArray(e1,e2)},e3)}
 						| TBinop(op,e1,e2) when (match com.platform with Cpp -> true | _ -> false) ->
 						| TBinop(op,e1,e2) when (match com.platform with Cpp -> true | _ -> false) ->
 							let e1 = replace e1 in
 							let e1 = replace e1 in
 							let temp_found = !found in
 							let temp_found = !found in
@@ -924,11 +939,6 @@ module Fusion = struct
 							let e2 = replace e2 in
 							let e2 = replace e2 in
 							found := !found || temp_found;
 							found := !found || temp_found;
 							{e with eexpr = TBinop(op,e1,e2)}
 							{e with eexpr = TBinop(op,e1,e2)}
-						| TArray(e1,e2) ->
-							let e1 = replace e1 in
-							let e2 = replace e2 in
-							if not !found && has_state_write ir then raise Exit;
-							{e with eexpr = TArray(e1,e2)}
 						| _ ->
 						| _ ->
 							Type.map_expr replace e
 							Type.map_expr replace e
 				in
 				in

+ 19 - 0
tests/unit/src/unit/issues/Issue6776.hx

@@ -0,0 +1,19 @@
+package unit.issues;
+
+class Issue6776 extends unit.Test {
+	function test1() {
+        var a = [1];
+        var i = 0;
+        var v = a[i];
+        a[i]++;
+        eq(1, v);
+	}
+
+	function test2() {
+        var a = [1];
+        var i = 0;
+        var v = a[i];
+        a[i] += 1;
+        eq(1, v);
+	}
+}