Browse Source

detect null expressions in invalid places (closes #4072)

Simon Krajewski 10 years ago
parent
commit
91722809c3
3 changed files with 41 additions and 7 deletions
  1. 37 5
      filters.ml
  2. 2 1
      tests/unit/src/unit/issues/Issue2989.hx
  3. 2 1
      tests/unit/src/unitstd/Reflect.unit.hx

+ 37 - 5
filters.ml

@@ -5,13 +5,45 @@ open Typecore
 
 (* PASS 1 begin *)
 
-let rec verify_ast e = match e.eexpr with
-	| TField(_) ->
+let rec verify_ast ctx e =
+	let not_null e e1 = match e1.eexpr with
+		| TConst TNull -> display_error ctx ("Invalid null expression: " ^ (s_expr_pretty "" (s_type (print_context())) e)) e.epos
+		| _ -> ()
+	in
+	let rec loop e = match e.eexpr with
+	| TField(e1,_) ->
+		not_null e e1;
 		()
+	| TArray(e1,e2) ->
+		not_null e e1;
+		loop e1;
+		loop e2
+	| TCall(e1,el) ->
+		not_null e e1;
+		loop e1;
+		List.iter loop el
+	| TUnop(_,_,e1) ->
+		not_null e e1;
+		loop e1
+	(* probably too messy *)
+(* 	| TBinop((OpEq | OpNotEq),e1,e2) ->
+		loop e1;
+		loop e2
+	| TBinop((OpAssign | OpAssignOp _),e1,e2) ->
+		not_null e e1;
+		loop e1;
+		loop e2
+	| TBinop(op,e1,e2) ->
+		not_null e e1;
+		not_null e e2;
+		loop e1;
+		loop e2 *)
 	| TTypeExpr(TClassDecl {cl_kind = KAbstractImpl a}) when not (Meta.has Meta.RuntimeValue a.a_meta) ->
 		error "Cannot use abstract as value" e.epos
 	| _ ->
-		Type.iter verify_ast e
+		Type.iter loop e
+	in
+	loop e
 
 (*
 	Wraps implicit blocks in TIf, TFor, TWhile, TFunction and TTry with real ones
@@ -1120,7 +1152,7 @@ let run com tctx main =
 		] in
 		List.iter (run_expression_filters tctx filters) new_types;
 		Analyzer.Run.run_on_types tctx new_types;
-		List.iter (iter_expressions [verify_ast]) new_types;
+		List.iter (iter_expressions [verify_ast tctx]) new_types;
 		let filters = [
 			Optimizer.sanitize com;
 			if com.config.pf_add_final_return then add_final_return else (fun e -> e);
@@ -1154,7 +1186,7 @@ let run com tctx main =
 			rename_local_vars tctx;
 		] in
 		List.iter (run_expression_filters tctx filters) new_types;
-		List.iter (iter_expressions [verify_ast]) new_types;
+		List.iter (iter_expressions [verify_ast tctx]) new_types;
 	end;
 	next_compilation();
 	List.iter (fun f -> f()) (List.rev com.filters); (* macros onGenerate etc. *)

+ 2 - 1
tests/unit/src/unit/issues/Issue2989.hx

@@ -4,7 +4,8 @@ class Issue2989 extends Test
 {
 	public function test()
 	{
-		Std.is(null,Array);
+		var n = null;
+		Std.is(n, Array);
 		new haxe.ds.Vector<Int>(10);
 	}
 }

+ 2 - 1
tests/unit/src/unitstd/Reflect.unit.hx

@@ -15,7 +15,8 @@ Reflect.field(c, "prop") == "prop";
 Reflect.field(c, "func")() == "foo";
 // As3 invokes the getter
 Reflect.field(c, "propAcc") == #if as3 "1" #else "0" #end;
-Reflect.field(null, null) == null;
+var n = null;
+Reflect.field(n, n) == null;
 Reflect.field(1, "foo") == null;
 
 // setField