瀏覽代碼

fix switch-side-effect-to-if-else properly (closes #5291)

Simon Krajewski 9 年之前
父節點
當前提交
68ead6cdda
共有 5 個文件被更改,包括 25 次插入10 次删除
  1. 5 7
      src/optimization/analyzerTexpr.ml
  2. 0 1
      src/syntax/ast.ml
  3. 0 1
      src/typing/common.ml
  4. 0 1
      src/typing/matcher.ml
  5. 20 0
      tests/unit/src/unit/issues/Issue5242.hx

+ 5 - 7
src/optimization/analyzerTexpr.ml

@@ -366,15 +366,10 @@ module Fusion = struct
 		in
 		loop e;
 		let can_be_fused v e =
-			let check_switch_variable v = match com.platform with
-				| Python | Lua when Meta.has Meta.SwitchVariable v.v_meta -> false
-				| _ -> true
-			in
 			let b = get_num_uses v <= 1 &&
 			        get_num_writes v = 0 &&
 			        can_be_used_as_value com e &&
-			        (Meta.has Meta.CompilerGenerated v.v_meta || config.AnalyzerConfig.optimize && config.AnalyzerConfig.fusion && type_change_ok com v.v_type e.etype && v.v_extra = None) &&
-			        check_switch_variable v
+			        (Meta.has Meta.CompilerGenerated v.v_meta || config.AnalyzerConfig.optimize && config.AnalyzerConfig.fusion && type_change_ok com v.v_type e.etype && v.v_extra = None)
 			in
 			(* let st = s_type (print_context()) in *)
 			(* if e.epos.pfile = "src/Main.hx" then print_endline (Printf.sprintf "%s: %i %i %b %s %s (%b %b %b %b %b) -> %b" v.v_name (get_num_uses v) (get_num_writes v) (can_be_used_as_value com e) (st v.v_type) (st e.etype) (Meta.has Meta.CompilerGenerated v.v_meta) config.Config.optimize config.Config.fusion (type_change_ok com v.v_type e.etype) (v.v_extra = None) b); *)
@@ -453,7 +448,10 @@ module Fusion = struct
 							let e1 = replace e1 in
 							{e with eexpr = TIf(e1,e2,eo)}
 						| TSwitch(e1,cases,edef) ->
-							let e1 = replace e1 in
+							let e1 = match com.platform with
+								| Lua | Python -> e1
+								| _ -> replace e1
+							in
 							{e with eexpr = TSwitch(e1,cases,edef)}
 						| TLocal v2 when v1 == v2 && not !affected ->
 							found := true;

+ 0 - 1
src/syntax/ast.ml

@@ -172,7 +172,6 @@ module Meta = struct
 		| StructAccess
 		| StructInit
 		| SuppressWarnings
-		| SwitchVariable
 		| This
 		| Throws
 		| To

+ 0 - 1
src/typing/common.ml

@@ -573,7 +573,6 @@ module MetaInfo = struct
 		| StructAccess -> ":structAccess",("Marks an extern class as using struct access('.') not pointer('->')",[Platform Cpp; UsedOn TClass])
 		| StructInit -> ":structInit",("Allows to initialize the class with a structure that matches constructor parameters",[UsedOn TClass])
 		| SuppressWarnings -> ":suppressWarnings",("Adds a SuppressWarnings annotation for the generated Java class",[Platform Java; UsedOn TClass])
-		| SwitchVariable -> ":switchVariable",("Used internally to mark switch subject variables",[Internal])
 		| TemplatedCall -> ":templatedCall",("Indicates that the first parameter of static call should be treated as a template arguement",[Platform Cpp; UsedOn TClassField])
 		| Throws -> ":throws",("Adds a 'throws' declaration to the generated function",[HasParam "Type as String"; Platform Java; UsedOn TClassField])
 		| This -> ":this",("Internally used to pass a 'this' expression to macros",[Internal; UsedOn TExpr])

+ 0 - 1
src/typing/matcher.ml

@@ -1059,7 +1059,6 @@ module Compile = struct
 				(e :: subjects,vars)
 			| _ ->
 				let v = gen_local ctx e.etype e.epos in
-				v.v_meta <- (Meta.SwitchVariable,[],e.epos) :: v.v_meta;
 				let ev = mk (TLocal v) e.etype e.epos in
 				(ev :: subjects,(v,e.epos,e) :: vars)
 		) ([],[]) subjects in

+ 20 - 0
tests/unit/src/unit/issues/Issue5242.hx

@@ -2,6 +2,7 @@ package unit.issues;
 
 class Issue5242 extends unit.Test {
 	function test() {
+		state = 0;
 		var buf = new StringBuf();
 		for (i in 0...5) {
 			switch (next()) {
@@ -18,6 +19,25 @@ class Issue5242 extends unit.Test {
 		eq("01245", buf.toString());
 	}
 
+	function test2() {
+		state = 0;
+		var buf = new StringBuf();
+		for (i in 0...5) {
+			var v = next();
+			switch (v) {
+				case "0":
+					buf.add("0");
+				case "1":
+					buf.add("1");
+				case "2":
+					buf.add("2");
+				default:
+					buf.add("" + state);
+			}
+		}
+		eq("01245", buf.toString());
+	}
+
 	static var state = 0;
 
 	static function next() {