Browse Source

[analyzer] consider expression-less TVars to be definitions

closes #10304
Simon Krajewski 4 years ago
parent
commit
c2bbef722b
2 changed files with 41 additions and 2 deletions
  1. 7 2
      src/optimization/analyzerTypes.ml
  2. 34 0
      tests/unit/src/unit/issues/Issue10304.hx

+ 7 - 2
src/optimization/analyzerTypes.ml

@@ -533,9 +533,14 @@ module Graph = struct
 					()
 			end;
 			let infer e = match e.eexpr with
-			| TVar(v,eo) ->
+			| TVar(v,_) ->
 				declare_var g v bb;
-				if eo <> None then add_var_def g bb v;
+				(* Technically, this was correct because without an assignment this isn't really a
+				   definition. However, there can be situations where uninitialized variables have to
+				   be considered in the data flow analysis, which requires proper SSA edges or otherwise
+				   stuff like #10304 happens. *)
+				(* if eo <> None then *)
+				add_var_def g bb v;
 			| TBinop(OpAssign,{eexpr = TLocal v},_) ->
 				add_var_def g bb v
 			| _ ->

+ 34 - 0
tests/unit/src/unit/issues/Issue10304.hx

@@ -0,0 +1,34 @@
+package unit.issues;
+
+import utest.Assert;
+
+private class PairIter<T> {
+	var data:Array<T>;
+	var x = 0;
+	var prev:T;
+	var cur:T;
+
+	public inline function new(data:Array<T>) {
+		this.data = data;
+	}
+
+	public inline function hasNext() {
+		return x < data.length;
+	}
+
+	public inline function next() {
+		prev = cur;
+		cur = data[x++];
+		return {prev: prev, cur: cur};
+	}
+}
+
+class Issue10304 extends Test {
+	function test() {
+		var buf = new StringBuf();
+		for (p in new PairIter([1, 2, 3])) {
+			buf.add('${p.prev} ${p.cur} ');
+		}
+		eq("null 1 1 2 2 3 ", buf.toString());
+	}
+}