Browse Source

fix term control flow check for switch in inliner (closes #4324)

Simon Krajewski 10 years ago
parent
commit
e86c9c1b12
3 changed files with 31 additions and 8 deletions
  1. 2 7
      analyzer.ml
  2. 9 1
      optimizer.ml
  3. 20 0
      tests/unit/src/unit/issues/Issue4324.hx

+ 2 - 7
analyzer.ml

@@ -897,13 +897,8 @@ module Ssa = struct
 						close join;
 						close join;
 						Some e
 						Some e
 					| None ->
 					| None ->
-						begin match e1.eexpr with
-							| TMeta((Meta.Exhaustive,_,_),_)
-							| TParenthesis({eexpr = TMeta((Meta.Exhaustive,_,_),_)}) ->
-								()
-							| _ ->
-								add_branch join ctx.cur_data e.epos;
-						end;
+						if not (Optimizer.is_exhaustive e1) then
+							add_branch join ctx.cur_data e.epos;
 						None
 						None
 				in
 				in
 				close_join_node ctx join e.epos;
 				close_join_node ctx join e.epos;

+ 9 - 1
optimizer.ml

@@ -44,6 +44,11 @@ let has_side_effect e =
 	with Exit ->
 	with Exit ->
 		true
 		true
 
 
+let rec is_exhaustive e1 = match e1.eexpr with
+	| TMeta((Meta.Exhaustive,_,_),_) -> true
+	| TMeta(_, e1) | TParenthesis e1 -> is_exhaustive e1
+	| _ -> false
+
 let mk_untyped_call name p params =
 let mk_untyped_call name p params =
 	{
 	{
 		eexpr = TCall({ eexpr = TLocal(alloc_unbound_var name t_dynamic); etype = t_dynamic; epos = p }, params);
 		eexpr = TCall({ eexpr = TLocal(alloc_unbound_var name t_dynamic); etype = t_dynamic; epos = p }, params);
@@ -404,7 +409,7 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			in_loop := old;
 			in_loop := old;
 			{ e with eexpr = TWhile (cond,eloop,flag) }
 			{ e with eexpr = TWhile (cond,eloop,flag) }
 		| TSwitch (e1,cases,def) when term ->
 		| TSwitch (e1,cases,def) when term ->
-			let term = term && def <> None in
+			let term = term && (def <> None || is_exhaustive e1) in
 			let cases = List.map (fun (el,e) ->
 			let cases = List.map (fun (el,e) ->
 				let el = List.map (map false) el in
 				let el = List.map (map false) el in
 				el, map term e
 				el, map term e
@@ -481,6 +486,9 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			{ e with eexpr = TFunction { tf_args = args; tf_expr = expr; tf_type = f.tf_type } }
 			{ e with eexpr = TFunction { tf_args = args; tf_expr = expr; tf_type = f.tf_type } }
 		| TConst TSuper ->
 		| TConst TSuper ->
 			error "Cannot inline function containing super" po
 			error "Cannot inline function containing super" po
+		| TMeta(m,e1) ->
+			let e1 = map term e1 in
+			{e with eexpr = TMeta(m,e1)}
 		| _ ->
 		| _ ->
 			Type.map_expr (map false) e
 			Type.map_expr (map false) e
 	in
 	in

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

@@ -0,0 +1,20 @@
+package unit.issues;
+
+class Issue4324 extends Test {
+
+	function test() {
+		eq(1, getInt());
+	}
+
+	static inline function getInt() {
+		switch (getTrue()) {
+			case true: return 1;
+			case false: return 2;
+		}
+	}
+
+	static function getTrue() {
+		return true;
+	}
+
+}