Przeglądaj źródła

disallow Void as throw value (closes #4982)

Simon Krajewski 9 lat temu
rodzic
commit
64108830c3

+ 9 - 5
src/optimization/analyzerTexprTransformer.ml

@@ -82,6 +82,9 @@ let rec func ctx bb tf t p =
 	let check_unbound_call v el =
 	let check_unbound_call v el =
 		if is_unbound_call_that_might_have_side_effects v el then ctx.has_unbound <- true
 		if is_unbound_call_that_might_have_side_effects v el then ctx.has_unbound <- true
 	in
 	in
+	let no_void t p =
+		if ExtType.is_void (follow t) then error "Cannot use Void as value" p
+	in
 	let rec value bb e = match e.eexpr with
 	let rec value bb e = match e.eexpr with
 		| TLocal v ->
 		| TLocal v ->
 			bb,e
 			bb,e
@@ -224,10 +227,7 @@ let rec func ctx bb tf t p =
 				bb,e
 				bb,e
 		in
 		in
 		let bb,e = loop bb e in
 		let bb,e = loop bb e in
-		begin match follow v.v_type with
-			| TAbstract({a_path=[],"Void"},_) -> error "Cannot use Void as value" e.epos
-			| _ -> ()
-		end;
+		no_void v.v_type e.epos;
 		let ev = mk (TLocal v) v.v_type e.epos in
 		let ev = mk (TLocal v) v.v_type e.epos in
 		let was_assigned = ref false in
 		let was_assigned = ref false in
 		let assign e =
 		let assign e =
@@ -475,7 +475,10 @@ let rec func ctx bb tf t p =
 			add_terminator bb e
 			add_terminator bb e
 		| TThrow e1 ->
 		| TThrow e1 ->
 			begin try
 			begin try
-				let mk_throw e1 = mk (TThrow e1) t_dynamic e.epos in
+				let mk_throw e1 =
+					no_void e1.etype e1.epos;
+					mk (TThrow e1) t_dynamic e.epos
+				in
 				block_element_value bb e1 mk_throw
 				block_element_value bb e1 mk_throw
 			with Exit ->
 			with Exit ->
 				let bb,e1 = value bb e1 in
 				let bb,e1 = value bb e1 in
@@ -483,6 +486,7 @@ let rec func ctx bb tf t p =
 					| [] -> add_cfg_edge bb bb_exit CFGGoto
 					| [] -> add_cfg_edge bb bb_exit CFGGoto
 					| _ -> List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGGoto) !b_try_stack;
 					| _ -> List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGGoto) !b_try_stack;
 				end;
 				end;
+				no_void e1.etype e1.epos;
 				add_terminator bb {e with eexpr = TThrow e1};
 				add_terminator bb {e with eexpr = TThrow e1};
 			end
 			end
 		(* side_effects *)
 		(* side_effects *)

+ 5 - 2
src/typing/type.ml

@@ -2464,5 +2464,8 @@ module Texpr = struct
 		| _ -> e
 		| _ -> e
 end
 end
 
 
-let print_if b e =
-	if b then print_endline (s_expr_pretty "" (s_type (print_context())) e)
+module ExtType = struct
+	let is_void = function
+		| TAbstract({a_path=[],"Void"},_) -> true
+		| _ -> false
+end

+ 9 - 0
tests/misc/projects/Issue4982/Main.hx

@@ -0,0 +1,9 @@
+class Main {
+    static function main() {
+        throw invalidChar(65);
+    }
+
+    static public function invalidChar(c) {
+        throw "error";
+    }
+}

+ 2 - 0
tests/misc/projects/Issue4982/compile-fail.hxml

@@ -0,0 +1,2 @@
+-main Main
+--interp

+ 1 - 0
tests/misc/projects/Issue4982/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:3: characters 14-29 : Cannot use Void as value