浏览代码

[analyzer] detect assignments to ref vars

closes #9543
Simon Krajewski 4 年之前
父节点
当前提交
6eab59f1d4
共有 2 个文件被更改,包括 42 次插入0 次删除
  1. 6 0
      src/optimization/analyzerTexprTransformer.ml
  2. 36 0
      tests/unit/src/unit/issues/Issue9543.hx

+ 6 - 0
src/optimization/analyzerTexprTransformer.ml

@@ -91,6 +91,10 @@ let rec func ctx bb tf t p =
 		ctx.name_stack <- s :: ctx.name_stack;
 		(fun () -> ctx.name_stack <- List.tl ctx.name_stack)
 	in
+	let check_ref v e = if ExtType.has_reference_semantics v.v_type then match (Texpr.skip e).eexpr with
+		| TLocal v' -> add_var_flag v' VCaptured
+		| _ -> ()
+	in
 	let rec value' bb e = match e.eexpr with
 		| TLocal _ | TIdent _ ->
 			bb,e
@@ -346,8 +350,10 @@ let rec func ctx bb tf t p =
 			add_texpr bb e;
 			bb
 		| TVar(v,Some e1) ->
+			check_ref v e1;
 			declare_var_and_assign bb v e1 e.epos
 		| TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) ->
+			check_ref v e2;
 			let assign e =
 				mk (TBinop(OpAssign,e1,e)) e.etype e.epos
 			in

+ 36 - 0
tests/unit/src/unit/issues/Issue9543.hx

@@ -0,0 +1,36 @@
+package unit.issues;
+
+private abstract A(String) {
+	public inline function new(s:String) {
+		this = s;
+	}
+
+	public function f(index:Int) {
+		return StringTools.fastCodeAt(this, index);
+	}
+
+	public inline function g(index:Int) {
+		return StringTools.fastCodeAt(this, index);
+	}
+}
+
+class Issue9543 extends unit.Test {
+	#if cpp
+	function testVar() {
+		var foo:Int = 0;
+		var bar:cpp.Reference<Int> = foo;
+		foo += 1;
+		eq(1, foo);
+		eq(1, bar);
+	}
+
+	function testAssign() {
+		var foo:Int = 0;
+		var bar:cpp.Reference<Int>;
+		bar = foo;
+		foo += 1;
+		eq(1, foo);
+		eq(1, bar);
+	}
+	#end
+}