浏览代码

remove the redundant cast on abstract operator overload, handle c# uint->long promotion in gencs filter (closes #3932)

Dan Korostelev 10 年之前
父节点
当前提交
21b601bf4f
共有 2 个文件被更改,包括 14 次插入3 次删除
  1. 13 0
      gencs.ml
  2. 1 3
      typer.ml

+ 13 - 0
gencs.ml

@@ -540,6 +540,19 @@ struct
 					else
 						ret
 
+				| TBinop ((OpAdd|OpSub|OpMult|OpDiv|OpMod|OpAnd|OpOr|OpXor) as op, e1, e2) ->
+					(*
+						https://msdn.microsoft.com/en-us/library/aa691330(v=vs.71).aspx
+						"if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long."
+						that conflicts with haxe behaviour so we have to cast back to uint there
+					*)
+					let is_uint t = match follow t with TAbstract ({a_path=[],"UInt"}, _) -> true | _ -> false in
+					let e = {e with eexpr = TBinop(op, run e1, run e2)} in
+					if is_uint e.etype && ((is_uint e1.etype && not (is_uint e2.etype)) || (is_uint e2.etype && not (is_uint e1.etype))) then
+						{e with eexpr = TCast(e, None)}
+					else
+						e
+
 				| _ -> Type.map_expr run e
 		in
 		run

+ 1 - 3
typer.ml

@@ -2198,9 +2198,7 @@ and type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p =
 								error (Printf.sprintf "The result of this operation (%s) is not compatible with declared return type %s" (st t_expected) (st tret)) p
 					end;
 				end;
-				let e = Codegen.binop op e1 e2 tret p in
-				mk_cast e tret p
-				(* Codegen.maybe_cast e tret *)
+				Codegen.binop op e1 e2 tret p
 			end else begin
 				let e = make_static_call ctx c cf map [e1;e2] tret p in
 				e