diff options
Diffstat (limited to 'lib/compiler/src')
| -rw-r--r-- | lib/compiler/src/core_lint.erl | 84 | 
1 files changed, 44 insertions, 40 deletions
| diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl index 25df33a287..d9653c816d 100644 --- a/lib/compiler/src/core_lint.erl +++ b/lib/compiler/src/core_lint.erl @@ -211,7 +211,7 @@ functions(Fs, Def, St0) ->  function({#c_var{name={_,_}},B}, Def, St) ->      %% Body must be a fun!      case B of -	#c_fun{} -> expr(B, Def, any, St); +	#c_fun{} -> expr(B, Def, 1, St);  	_ -> add_error({illegal_expr,St#lint.func}, St)      end. @@ -247,40 +247,42 @@ gbody(E, Def, Rt, St0) ->  	false -> St1      end. -gexpr(#c_var{name=N}, Def, _Rt, St) when is_atom(N); is_integer(N) -> -    expr_var(N, Def, St); -gexpr(#c_literal{}, _Def, _Rt, St) -> St; -gexpr(#c_cons{hd=H,tl=T}, Def, _Rt, St) -> -    gexpr_list([H,T], Def, St); -gexpr(#c_tuple{es=Es}, Def, _Rt, St) -> -    gexpr_list(Es, Def, St); -gexpr(#c_map{es=Es}, Def, _Rt, St) -> -    gexpr_list(Es, Def, St); -gexpr(#c_map_pair{key=K,val=V}, Def, _Rt, St) -> -    gexpr_list([K,V], Def, St); -gexpr(#c_binary{segments=Ss}, Def, _Rt, St) -> -    gbitstr_list(Ss, Def, St); +gexpr(#c_var{name=N}, Def, Rt, St) when is_atom(N); is_integer(N) -> +    return_match(Rt, 1, expr_var(N, Def, St)); +gexpr(#c_literal{}, _Def, Rt, St) -> +    return_match(Rt, 1, St); +gexpr(#c_cons{hd=H,tl=T}, Def, Rt, St) -> +    return_match(Rt, 1, gexpr_list([H,T], Def, St)); +gexpr(#c_tuple{es=Es}, Def, Rt, St) -> +    return_match(Rt, 1, gexpr_list(Es, Def, St)); +gexpr(#c_map{es=Es}, Def, Rt, St) -> +    return_match(Rt, 1, gexpr_list(Es, Def, St)); +gexpr(#c_map_pair{key=K,val=V}, Def, Rt, St) -> +    return_match(Rt, 1, gexpr_list([K,V], Def, St)); +gexpr(#c_binary{segments=Ss}, Def, Rt, St) -> +    return_match(Rt, 1, gbitstr_list(Ss, Def, St));  gexpr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) -> -    St1 = gexpr(Arg, Def, any, St0),		%Ignore values -    gbody(B, Def, Rt, St1); +    St1 = gexpr(Arg, Def, 1, St0), +    return_match(Rt, 1, gbody(B, Def, Rt, St1));  gexpr(#c_let{vars=Vs,arg=Arg,body=B}, Def, Rt, St0) ->      St1 = gbody(Arg, Def, let_varcount(Vs), St0), %This is a guard body      {Lvs,St2} = variable_list(Vs, St1),      gbody(B, union(Lvs, Def), Rt, St2);  gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record},                args=[Arg,#c_literal{val=Tag},#c_literal{val=Size}]}, -      Def, 1, St) when is_atom(Tag), is_integer(Size) -> -    gexpr(Arg, Def, 1, St); +      Def, Rt, St) when is_atom(Tag), is_integer(Size) -> +    return_match(Rt, 1, gexpr(Arg, Def, 1, St));  gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record}}, -      _Def, 1, St) -> -    add_error({illegal_guard,St#lint.func}, St); +      _Def, Rt, St) -> +    return_match(Rt, 1, add_error({illegal_guard,St#lint.func}, St));  gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=Name},args=As}, -      Def, 1, St) when is_atom(Name) -> +      Def, Rt, St0) when is_atom(Name) -> +    St1 = return_match(Rt, 1, St0),      case is_guard_bif(Name, length(As)) of          true -> -            gexpr_list(As, Def, St); +            gexpr_list(As, Def, St1);          false -> -            add_error({illegal_guard,St#lint.func}, St) +            add_error({illegal_guard,St1#lint.func}, St1)      end;  gexpr(#c_primop{name=#c_literal{val=A},args=As}, Def, _Rt, St0) when is_atom(A) ->      gexpr_list(As, Def, St0); @@ -319,23 +321,25 @@ is_guard_bif(Name, Arity) ->  %% expr(Expr, Defined, RetCount, State) -> State. -expr(#c_var{name={_,_}=FA}, Def, _Rt, St) -> -    expr_fname(FA, Def, St); -expr(#c_var{name=N}, Def, _Rt, St) -> expr_var(N, Def, St); -expr(#c_literal{}, _Def, _Rt, St) -> St; -expr(#c_cons{hd=H,tl=T}, Def, _Rt, St) -> -    expr_list([H,T], Def, St); -expr(#c_tuple{es=Es}, Def, _Rt, St) -> -    expr_list(Es, Def, St); -expr(#c_map{es=Es}, Def, _Rt, St) -> -    expr_list(Es, Def, St); -expr(#c_map_pair{key=K,val=V},Def,_Rt,St) -> -    expr_list([K,V],Def,St); -expr(#c_binary{segments=Ss}, Def, _Rt, St) -> -    bitstr_list(Ss, Def, St); +expr(#c_var{name={_,_}=FA}, Def, Rt, St) -> +    return_match(Rt, 1, expr_fname(FA, Def, St)); +expr(#c_var{name=N}, Def, Rt, St) -> +    return_match(Rt, 1, expr_var(N, Def, St)); +expr(#c_literal{}, _Def, Rt, St) -> +    return_match(Rt, 1, St); +expr(#c_cons{hd=H,tl=T}, Def, Rt, St) -> +    return_match(Rt, 1, expr_list([H,T], Def, St)); +expr(#c_tuple{es=Es}, Def, Rt, St) -> +    return_match(Rt, 1, expr_list(Es, Def, St)); +expr(#c_map{es=Es}, Def, Rt, St) -> +    return_match(Rt, 1, expr_list(Es, Def, St)); +expr(#c_map_pair{key=K,val=V}, Def, Rt, St) -> +    return_match(Rt, 1, expr_list([K,V], Def, St)); +expr(#c_binary{segments=Ss}, Def, Rt, St) -> +    return_match(Rt, 1, bitstr_list(Ss, Def, St));  expr(#c_fun{vars=Vs,body=B}, Def, Rt, St0) ->      {Vvs,St1} = variable_list(Vs, St0), -    return_match(Rt, 1, body(B, union(Vvs, Def), any, St1)); +    return_match(Rt, 1, body(B, union(Vvs, Def), 1, St1));  expr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) ->      St1 = expr(Arg, Def, 1, St0),      body(B, Def, Rt, St1); @@ -361,9 +365,9 @@ expr(#c_receive{clauses=Cs,timeout=T,action=A}, Def, Rt, St0) ->      St1 = expr(T, Def, 1, St0),      St2 = body(A, Def, Rt, St1),      clauses(Cs, Def, 1, Rt, St2); -expr(#c_apply{op=Op,args=As}, Def, _Rt, St0) -> +expr(#c_apply{op=Op,args=As}, Def, Rt, St0) ->      St1 = apply_op(Op, Def, length(As), St0), -    expr_list(As, Def, St1); +    return_match(Rt, 1, expr_list(As, Def, St1));  expr(#c_call{module=M,name=N,args=As}, Def, _Rt, St0) ->      St1 = expr(M, Def, 1, St0),      St2 = expr(N, Def, 1, St1), | 
