2
0
Эх сурвалжийг харах

[analyzer] respect C#'s wonky eval order in structures

see #7531
Simon Krajewski 7 жил өмнө
parent
commit
db6823aa93

+ 4 - 3
src/optimization/analyzerTexpr.ml

@@ -789,7 +789,7 @@ module Fusion = struct
 						blocked := old;
 						e
 					in
-					let handle_el el =
+					let handle_el' el =
 						(* This mess deals with the fact that the order of evaluation is undefined for call
 							arguments on these targets. Even if we find a replacement, we pretend that we
 							didn't in order to find possible interferences in later call arguments. *)
@@ -804,7 +804,7 @@ module Fusion = struct
 						found := !really_found;
 						el
 					in
-					let handle_el = if not (target_handles_side_effect_order com) then handle_el else List.map replace in
+					let handle_el = if not (target_handles_side_effect_order com) then handle_el' else List.map replace in
 					let handle_call e2 el = match com.platform with
 						| Neko ->
 							(* Neko has this reversed at the moment (issue #4787) *)
@@ -925,7 +925,8 @@ module Fusion = struct
 							if not !found && (((has_state_read ir || has_any_field_read ir)) || has_state_write ir || has_any_field_write ir) then raise Exit;
 							{e with eexpr = TCall(e1,el)}
 						| TObjectDecl fl ->
-							let el = handle_el (List.map snd fl) in
+							(* The C# generator has trouble with evaluation order in structures (#7531). *)
+							let el = (match com.platform with Cs -> handle_el' | _ -> handle_el) (List.map snd fl) in
 							if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit;
 							{e with eexpr = TObjectDecl (List.map2 (fun (s,_) e -> s,e) fl el)}
 						| TArrayDecl el ->

+ 16 - 0
tests/unit/src/unit/issues/Issue7531.hx

@@ -0,0 +1,16 @@
+package unit.issues;
+
+class Issue7531 extends unit.Test {
+	function test() {
+		var kv = get();
+		eq(0, kv.key);
+		eq(1, kv.value);
+	}
+
+	static var arr = [1, 2, 3];
+	static var idx = 0;
+
+	static function get() {
+		return {value:arr[idx], key:idx++};
+	}
+}