Explorar o código

make sure all used inline-ctor fields are initialized (closes #4703) (closes #4942)

Simon Krajewski %!s(int64=9) %!d(string=hai) anos
pai
achega
18e99b18a3

+ 1 - 1
src/optimization/filters.ml

@@ -1035,8 +1035,8 @@ let run com tctx main =
 	(* PASS 1: general expression filters *)
 	let filters = [
 		Codegen.AbstractCast.handle_abstract_casts tctx;
-		check_local_vars_init;
 		Optimizer.inline_constructors tctx;
+		check_local_vars_init;
 		Optimizer.reduce_expression tctx;
 		captured_vars com;
 	] in

+ 16 - 12
src/optimization/optimizer.ml

@@ -1413,6 +1413,16 @@ let inline_constructors ctx e =
 		v.v_id <- -v.v_id;
 		vars := IntMap.add v.v_id ii !vars;
 	in
+	let get_field_var v s =
+		let ii = IntMap.find v.v_id !vars in
+		PMap.find s ii.ii_fields
+	in
+	let add_field_var v s t =
+		let ii = IntMap.find v.v_id !vars in
+		let v' = alloc_var (Printf.sprintf "%s_%s" v.v_name s) t in
+		ii.ii_fields <- PMap.add s v' ii.ii_fields;
+		v'
+	in
 	let int_field_name i =
 		if i < 0 then "n" ^ (string_of_int (-i))
 		else (string_of_int i)
@@ -1477,7 +1487,9 @@ let inline_constructors ctx e =
 					()
 			in
 			loop [] e1
-		| TBinop(OpAssign,{eexpr = TField({eexpr = TLocal v},_)},e2) when v.v_id < 0 ->
+		| TBinop(OpAssign,({eexpr = TField({eexpr = TLocal v},fa)} as e1),e2) when v.v_id < 0 ->
+			let s = field_name fa in
+			(try ignore(get_field_var v s) with Not_found -> ignore(add_field_var v s e1.etype));
 			find_locals e2
 		| TField({eexpr = TLocal v},fa) when v.v_id < 0 ->
 			begin match extract_field fa with
@@ -1503,20 +1515,12 @@ let inline_constructors ctx e =
 	in
 	find_locals e;
 	(* Pass 2 *)
-	let get_field_var v s =
-		let ii = IntMap.find v.v_id !vars in
-		PMap.find s ii.ii_fields
-	in
-	let add_field_var v s t =
-		let ii = IntMap.find v.v_id !vars in
-		let v' = alloc_var (Printf.sprintf "%s_%s" v.v_name s) t in
-		ii.ii_fields <- PMap.add s v' ii.ii_fields;
-		v'
-	in
 	let inline v p =
 		try
 			let ii = IntMap.find v.v_id !vars in
-			Some ii.ii_expr
+			let el = PMap.fold (fun v acc -> (mk (TVar(v,None)) ctx.t.tvoid p) :: acc) ii.ii_fields [] in
+			let e = {ii.ii_expr with eexpr = TBlock (el @ [ii.ii_expr])} in
+			Some e
 		with Not_found ->
 			None
 	in

+ 2 - 1
tests/optimization/src/Test.hx

@@ -68,10 +68,11 @@ class Test {
 
 	@:js('
 		var a = 0;
+		var b_x;
 		var c_x = 1;
 		var c_y = "c";
 		a = 1;
-		var b_x = 2;
+		b_x = 2;
 		var b_y = "b";
 		b_x = 1;
 	')

+ 25 - 0
tests/unit/src/unit/issues/Issue4703.hx

@@ -0,0 +1,25 @@
+package unit.issues;
+
+private class C {
+	public var x:Int;
+	public var y:Int;
+
+	public inline function new(x:Int) {
+		this.x = 1;
+	}
+}
+
+class Issue4703 extends Test {
+
+	function test() {
+		var m = new C(12);
+		if (Math.random() > 0.5) {
+			m.y = 1;
+		} else {
+			m.y = 2;
+		}
+		useeeee(m.y);
+	}
+
+	static function useeeee(d:Dynamic) { }
+}