1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% Purpose : Do necessary checking of Core Erlang code. 21 22%% Check Core module for errors. Seeing this module is used in the 23%% compiler after optimisations we do more checking than would be 24%% necessary after just parsing. Don't check all constructs. 25%% 26%% We check the following: 27%% 28%% All referred functions, called and exported, are defined. 29%% Format of export list. 30%% Format of attributes 31%% Used variables are defined. 32%% Variables in let and funs. 33%% Patterns case clauses. 34%% Values only as multiple values/variables/patterns. 35%% Return same number of values as requested 36%% Correct number of arguments 37%% Consistency of values/variables 38%% Consistency of function return values/calls. 39%% 40%% We keep the names defined variables and functions in a ordered list 41%% of variable names and function name/arity pairs. 42 43-module(core_lint). 44 45-export([module/1,module/2,format_error/1]). 46 47-import(lists, [reverse/1,all/2,foldl/3]). 48-import(ordsets, [add_element/2,is_element/2,union/2]). 49 50-include("core_parse.hrl"). 51 52%%----------------------------------------------------------------------- 53%% Types used in this module 54 55-type fa() :: {atom(), arity()}. 56 57-type err_desc() :: 'invalid_attributes' | 'invalid_exports' 58 | {'arg_mismatch', fa()} | {'bittype_unit', fa()} 59 | {'illegal_expr', fa()} | {'illegal_guard', fa()} 60 | {'illegal_pattern', fa()} | {'illegal_try', fa()} 61 | {'not_bs_pattern', fa()} | {'not_pattern', fa()} 62 | {'not_var', fa()} | {'pattern_mismatch', fa()} 63 | {'return_mismatch', fa()} | {'undefined_function', fa()} 64 | {'duplicate_var', cerl:var_name(), fa()} 65 | {'unbound_var', cerl:var_name(), fa()} 66 | {'undefined_function', fa(), fa()} 67 | {'tail_segment_not_at_end', fa()}. 68 69-type error() :: {'none', module(), err_desc()}. 70-type warning() :: {module(), term()}. 71 72%%----------------------------------------------------------------------- 73%% Define the lint state record. 74 75-record(lint, {module :: module(), % Current module 76 func :: fa() | 'undefined', % Current function 77 errors = [] :: [error()], % Errors 78 warnings= [] :: [warning()]}). % Warnings 79 80%%---------------------------------------------------------------------- 81 82%% format_error(Error) 83%% Return a string describing the error. 84 85-spec format_error(err_desc()) -> [char() | list()]. 86 87format_error(invalid_attributes) -> "invalid attributes"; 88format_error(invalid_exports) -> "invalid exports"; 89format_error({arg_mismatch,{F,A}}) -> 90 io_lib:format("argument count mismatch in ~w/~w", [F,A]); 91format_error({bittype_unit,{F,A}}) -> 92 io_lib:format("unit without size in bit syntax pattern/expression in ~w/~w", [F,A]); 93format_error({illegal_expr,{F,A}}) -> 94 io_lib:format("illegal expression in ~w/~w", [F,A]); 95format_error({illegal_guard,{F,A}}) -> 96 io_lib:format("illegal guard expression in ~w/~w", [F,A]); 97format_error({illegal_pattern,{F,A}}) -> 98 io_lib:format("illegal pattern in ~w/~w", [F,A]); 99format_error({illegal_try,{F,A}}) -> 100 io_lib:format("illegal try expression in ~w/~w", [F,A]); 101format_error({not_bs_pattern,{F,A}}) -> 102 io_lib:format("expecting bit syntax pattern in ~w/~w", [F,A]); 103format_error({not_pattern,{F,A}}) -> 104 io_lib:format("expecting pattern in ~w/~w", [F,A]); 105format_error({not_var,{F,A}}) -> 106 io_lib:format("expecting variable in ~w/~w", [F,A]); 107format_error({pattern_mismatch,{F,A}}) -> 108 io_lib:format("pattern count mismatch in ~w/~w", [F,A]); 109format_error({return_mismatch,{F,A}}) -> 110 io_lib:format("return count mismatch in ~w/~w", [F,A]); 111format_error({undefined_function,{F,A}}) -> 112 io_lib:format("function ~w/~w undefined", [F,A]); 113format_error({duplicate_var,N,{F,A}}) -> 114 io_lib:format("duplicate variable ~s in ~w/~w", [N,F,A]); 115format_error({unbound_var,N,{F,A}}) -> 116 io_lib:format("unbound variable ~s in ~w/~w", [N,F,A]); 117format_error({undefined_function,{F1,A1},{F2,A2}}) -> 118 io_lib:format("undefined function ~w/~w in ~w/~w", [F1,A1,F2,A2]); 119format_error({tail_segment_not_at_end,{F,A}}) -> 120 io_lib:format("binary tail segment not at end in ~w/~w", [F,A]). 121 122-type ret() :: {'ok', [{module(), [warning(),...]}]} 123 | {'error', [{module(), [error(),...]}], 124 [{module(), [warning(),...]}]}. 125 126-spec module(cerl:c_module()) -> ret(). 127 128module(M) -> module(M, []). 129 130-spec module(cerl:c_module(), [compile:option()]) -> ret(). 131 132module(#c_module{name=M,exports=Es,attrs=As,defs=Ds}, _Opts) -> 133 Defined = defined_funcs(Ds), 134 St0 = #lint{module=M#c_literal.val}, 135 St1 = check_exports(Es, St0), 136 St2 = check_attrs(As, St1), 137 St3 = module_defs(Ds, Defined, St2), 138 St4 = check_state(Es, Defined, St3), 139 return_status(St4). 140 141%% defined_funcs([FuncDef]) -> [Fname]. 142 143defined_funcs(Fs) -> 144 foldl(fun ({#c_var{name={_I,_A}=IA},_}, Def) -> 145 add_element(IA, Def) 146 end, [], Fs). 147 148%% return_status(State) -> 149%% {ok,[Warning]} | {error,[Error],[Warning]} 150%% Pack errors and warnings properly and return ok | error. 151 152return_status(St) -> 153 Ws = reverse(St#lint.warnings), 154 case reverse(St#lint.errors) of 155 [] -> {ok,[{St#lint.module,Ws}]}; 156 Es -> {error,[{St#lint.module,Es}],[{St#lint.module,Ws}]} 157 end. 158 159%% add_error(ErrorDescriptor, State) -> State' 160%% add_warning(ErrorDescriptor, State) -> State' 161%% Note that we don't use line numbers here. 162 163add_error(E, St) -> St#lint{errors=[{none,?MODULE,E}|St#lint.errors]}. 164 165%%add_warning(W, St) -> St#lint{warnings=[{none,core_lint,W}|St#lint.warnings]}. 166 167check_exports(Es, St) -> 168 case all(fun (#c_var{name={Name,Arity}}) 169 when is_atom(Name), is_integer(Arity) -> true; 170 (_) -> false 171 end, Es) of 172 true -> St; 173 false -> add_error(invalid_exports, St) 174 end. 175 176check_attrs(As, St) -> 177 case all(fun ({#c_literal{},#c_literal{}}) -> true; 178 (_) -> false 179 end, As) of 180 true -> St; 181 false -> add_error(invalid_attributes, St) 182 end. 183 184check_state(Es, Defined, St) -> 185 foldl(fun (#c_var{name={_N,_A}=F}, St1) -> 186 case is_element(F, Defined) of 187 true -> St1; 188 false -> add_error({undefined_function,F}, St) 189 end 190 end, St, Es). 191 192%% module_defs(CoreBody, Defined, State) -> State. 193 194module_defs(B, Def, St) -> 195 %% Set top level function name. 196 foldl(fun (Func, St0) -> 197 {#c_var{name={_F,_A}=FA},_} = Func, 198 St1 = St0#lint{func=FA}, 199 function(Func, Def, St1) 200 end, St, B). 201 202%% functions([Fdef], Defined, State) -> State. 203 204functions(Fs, Def, St0) -> 205 foldl(fun (F, St) -> function(F, Def, St) end, St0, Fs). 206 207%% function(CoreFunc, Defined, State) -> State. 208 209function({#c_var{name={_,_}},B}, Def, St) -> 210 %% Body must be a fun! 211 case B of 212 #c_fun{} -> expr(B, Def, 1, St); 213 _ -> add_error({illegal_expr,St#lint.func}, St) 214 end. 215 216%% body(Expr, Defined, RetCount, State) -> State. 217 218body(#c_values{es=Es}, Def, Rt, St) -> 219 return_match(Rt, length(Es), expr_list(Es, Def, St)); 220body(E, Def, Rt, St0) -> 221 St1 = expr(E, Def, Rt, St0), 222 case is_simple_top(E) of 223 true -> return_match(Rt, 1, St1); 224 false -> St1 225 end. 226 227%% guard(Expr, Defined, State) -> State. 228%% Guards are boolean expressions with test wrapped in a protected. 229 230guard(Expr, Def, St) -> gexpr(Expr, Def, 1, St). 231 232%% guard_list([Expr], Defined, State) -> State. 233 234%% guard_list(Es, Def, St0) -> 235%% foldl(fun (E, St) -> guard(E, Def, St) end, St0, Es). 236 237%% gbody(Expr, Defined, RetCount, State) -> State. 238 239gbody(#c_values{es=Es}, Def, Rt, St) -> 240 return_match(Rt, length(Es), gexpr_list(Es, Def, St)); 241gbody(E, Def, Rt, St0) -> 242 St1 = gexpr(E, Def, Rt, St0), 243 case is_simple_top(E) of 244 true -> return_match(Rt, 1, St1); 245 false -> St1 246 end. 247 248gexpr(#c_var{name=N}, Def, Rt, St) when is_atom(N); is_integer(N) -> 249 return_match(Rt, 1, expr_var(N, Def, St)); 250gexpr(#c_literal{}, _Def, Rt, St) -> 251 return_match(Rt, 1, St); 252gexpr(#c_cons{hd=H,tl=T}, Def, Rt, St) -> 253 return_match(Rt, 1, gexpr_list([H,T], Def, St)); 254gexpr(#c_tuple{es=Es}, Def, Rt, St) -> 255 return_match(Rt, 1, gexpr_list(Es, Def, St)); 256gexpr(#c_map{es=Es}, Def, Rt, St) -> 257 return_match(Rt, 1, gexpr_list(Es, Def, St)); 258gexpr(#c_map_pair{key=K,val=V}, Def, Rt, St) -> 259 return_match(Rt, 1, gexpr_list([K,V], Def, St)); 260gexpr(#c_binary{segments=Ss}, Def, Rt, St) -> 261 return_match(Rt, 1, gbitstr_list(Ss, Def, St)); 262gexpr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) -> 263 St1 = gexpr(Arg, Def, 1, St0), 264 return_match(Rt, 1, gbody(B, Def, Rt, St1)); 265gexpr(#c_let{vars=Vs,arg=Arg,body=B}, Def, Rt, St0) -> 266 St1 = gbody(Arg, Def, let_varcount(Vs), St0), %This is a guard body 267 {Lvs,St2} = variable_list(Vs, St1), 268 gbody(B, union(Lvs, Def), Rt, St2); 269gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record}, 270 args=[Arg,#c_literal{val=Tag},#c_literal{val=Size}]}, 271 Def, Rt, St) when is_atom(Tag), is_integer(Size) -> 272 return_match(Rt, 1, gexpr(Arg, Def, 1, St)); 273gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=is_record}}, 274 _Def, Rt, St) -> 275 return_match(Rt, 1, add_error({illegal_guard,St#lint.func}, St)); 276gexpr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=Name},args=As}, 277 Def, Rt, St0) when is_atom(Name) -> 278 St1 = return_match(Rt, 1, St0), 279 case is_guard_bif(Name, length(As)) of 280 true -> 281 gexpr_list(As, Def, St1); 282 false -> 283 add_error({illegal_guard,St1#lint.func}, St1) 284 end; 285gexpr(#c_primop{name=#c_literal{val=A},args=As}, Def, _Rt, St0) when is_atom(A) -> 286 gexpr_list(As, Def, St0); 287gexpr(#c_try{arg=E,vars=[#c_var{name=X}],body=#c_var{name=X}, 288 evars=[#c_var{},#c_var{}],handler=#c_literal{val=false}}, 289 Def, Rt, St) -> 290 gbody(E, Def, Rt, St); 291gexpr(#c_case{arg=Arg,clauses=Cs}, Def, Rt, St0) -> 292 PatCount = case_patcount(Cs), 293 St1 = gbody(Arg, Def, PatCount, St0), 294 clauses(Cs, Def, PatCount, Rt, St1); 295gexpr(_Core, _, _, St) -> 296 %%io:fwrite("clint gexpr: ~p~n", [_Core]), 297 add_error({illegal_guard,St#lint.func}, St). 298 299%% gexpr_list([Expr], Defined, State) -> State. 300 301gexpr_list(Es, Def, St0) -> 302 foldl(fun (E, St) -> gexpr(E, Def, 1, St) end, St0, Es). 303 304%% gbitstr_list([Elem], Defined, State) -> State. 305 306gbitstr_list(Es, Def, St0) -> 307 foldl(fun (E, St) -> gbitstr(E, Def, St) end, St0, Es). 308 309gbitstr(#c_bitstr{val=V,size=S}, Def, St) -> 310 gexpr_list([V,S], Def, St). 311 312%% is_guard_bif(Name, Arity) -> Boolean. 313 314is_guard_bif(Name, Arity) -> 315 erl_internal:guard_bif(Name, Arity) 316 orelse erl_internal:arith_op(Name, Arity) 317 orelse erl_internal:bool_op(Name, Arity) 318 orelse erl_internal:comp_op(Name, Arity). 319 320%% expr(Expr, Defined, RetCount, State) -> State. 321 322expr(#c_var{name={_,_}=FA}, Def, Rt, St) -> 323 return_match(Rt, 1, expr_fname(FA, Def, St)); 324expr(#c_var{name=N}, Def, Rt, St) -> 325 return_match(Rt, 1, expr_var(N, Def, St)); 326expr(#c_literal{}, _Def, Rt, St) -> 327 return_match(Rt, 1, St); 328expr(#c_cons{hd=H,tl=T}, Def, Rt, St) -> 329 return_match(Rt, 1, expr_list([H,T], Def, St)); 330expr(#c_tuple{es=Es}, Def, Rt, St) -> 331 return_match(Rt, 1, expr_list(Es, Def, St)); 332expr(#c_map{es=Es}, Def, Rt, St) -> 333 return_match(Rt, 1, expr_list(Es, Def, St)); 334expr(#c_map_pair{key=K,val=V}, Def, Rt, St) -> 335 return_match(Rt, 1, expr_list([K,V], Def, St)); 336expr(#c_binary{segments=Ss}, Def, Rt, St) -> 337 return_match(Rt, 1, bitstr_list(Ss, Def, St)); 338expr(#c_fun{vars=Vs,body=B}, Def, Rt, St0) -> 339 {Vvs,St1} = variable_list(Vs, St0), 340 return_match(Rt, 1, body(B, union(Vvs, Def), 1, St1)); 341expr(#c_seq{arg=Arg,body=B}, Def, Rt, St0) -> 342 St1 = expr(Arg, Def, 1, St0), 343 body(B, Def, Rt, St1); 344expr(#c_let{vars=Vs,arg=Arg,body=B}, Def, Rt, St0) -> 345 St1 = body(Arg, Def, let_varcount(Vs), St0), %This is a body 346 {Lvs,St2} = variable_list(Vs, St1), 347 body(B, union(Lvs, Def), Rt, St2); 348expr(#c_letrec{defs=Fs,body=B}, Def0, Rt, St0) -> 349 Def1 = union(defined_funcs(Fs), Def0), %All defined stuff 350 St1 = functions(Fs, Def1, St0), 351 body(B, Def1, Rt, St1#lint{func=St0#lint.func}); 352expr(#c_case{arg=Arg,clauses=Cs}, Def, Rt, St0) -> 353 Pc = case_patcount(Cs), 354 St1 = body(Arg, Def, Pc, St0), 355 clauses(Cs, Def, Pc, Rt, St1); 356expr(#c_receive{clauses=Cs,timeout=T,action=A}, Def, Rt, St0) -> 357 St1 = expr(T, Def, 1, St0), 358 St2 = body(A, Def, Rt, St1), 359 clauses(Cs, Def, 1, Rt, St2); 360expr(#c_apply{op=Op,args=As}, Def, Rt, St0) -> 361 St1 = apply_op(Op, Def, length(As), St0), 362 return_match(Rt, 1, expr_list(As, Def, St1)); 363expr(#c_call{module=#c_literal{val=erlang},name=#c_literal{val=Name},args=As}, 364 Def, Rt, St0) when is_atom(Name) -> 365 St1 = expr_list(As, Def, St0), 366 case erl_bifs:is_exit_bif(erlang, Name, length(As)) of 367 true -> St1; 368 false -> return_match(Rt, 1, St1) 369 end; 370expr(#c_call{module=M,name=N,args=As}, Def, _Rt, St0) -> 371 St1 = expr(M, Def, 1, St0), 372 St2 = expr(N, Def, 1, St1), 373 expr_list(As, Def, St2); 374expr(#c_primop{name=#c_literal{val=A},args=As}, Def, Rt, St0) when is_atom(A) -> 375 St1 = expr_list(As, Def, St0), 376 case A of 377 match_fail -> St1; 378 _ -> return_match(Rt, 1, St1) 379 end; 380expr(#c_catch{body=B}, Def, Rt, St) -> 381 return_match(Rt, 1, body(B, Def, 1, St)); 382expr(#c_try{arg=A,vars=Vs,body=B,evars=Evs,handler=H}, Def, Rt, St0) -> 383 St1 = case Evs of 384 [_, _, _] -> St0; 385 _ -> add_error({illegal_try,St0#lint.func}, St0) 386 end, 387 St2 = body(A, Def, let_varcount(Vs), St1), 388 {Ns,St3} = variable_list(Vs, St2), 389 St4 = body(B, union(Ns, Def), Rt, St3), 390 {Ens,St5} = variable_list(Evs, St4), 391 body(H, union(Ens, Def), Rt, St5); 392expr(_Other, _, _, St) -> 393 %%io:fwrite("clint expr: ~p~n", [_Other]), 394 add_error({illegal_expr,St#lint.func}, St). 395 396%% expr_list([Expr], Defined, State) -> State. 397 398expr_list(Es, Def, St0) -> 399 foldl(fun (E, St) -> expr(E, Def, 1, St) end, St0, Es). 400 401%% bitstr_list([Elem], Defined, State) -> State. 402 403bitstr_list(Es, Def, St0) -> 404 foldl(fun (E, St) -> bitstr(E, Def, St) end, St0, Es). 405 406bitstr(#c_bitstr{val=V,size=S}, Def, St) -> 407 expr_list([V,S], Def, St). 408 409%% apply_op(Op, Defined, ArgCount, State) -> State. 410%% A apply op is either an fname or an expression. 411 412apply_op(#c_var{name={_I,A}=IA}, Def, Ac, St0) -> 413 St1 = expr_fname(IA, Def, St0), 414 arg_match(Ac, A, St1); 415apply_op(E, Def, _, St) -> expr(E, Def, 1, St). %Hard to check 416 417%% expr_var(VarName, Defined, State) -> State. 418 419expr_var(N, Def, St) -> 420 case is_element(N, Def) of 421 true -> St; 422 false -> add_error({unbound_var,N,St#lint.func}, St) 423 end. 424 425%% expr_fname(Fname, Defined, State) -> State. 426 427expr_fname(Fname, Def, St) -> 428 case is_element(Fname, Def) of 429 true -> St; 430 false -> add_error({undefined_function,Fname,St#lint.func}, St) 431 end. 432 433%% let_varcount([Var]) -> int(). 434 435let_varcount([]) -> any; %Ignore values 436let_varcount(Es) -> length(Es). 437 438%% case_patcount([Clause]) -> int(). 439 440case_patcount([#c_clause{pats=Ps}|_]) -> length(Ps). 441 442%% clauses([Clause], Defined, PatCount, RetCount, State) -> State. 443 444clauses(Cs, Def, Pc, Rt, St0) -> 445 foldl(fun (C, St) -> clause(C, Def, Pc, Rt, St) end, St0, Cs). 446 447%% clause(Clause, Defined, PatCount, RetCount, State) -> State. 448 449clause(#c_clause{pats=Ps,guard=G,body=B}, Def0, Pc, Rt, St0) -> 450 St1 = pattern_match(Pc, length(Ps), St0), 451 {Pvs,St2} = pattern_list(Ps, Def0, St1), 452 Def1 = union(Pvs, Def0), 453 St3 = guard(G, Def1, St2), 454 body(B, Def1, Rt, St3). 455 456%% variable(Var, [PatVar], State) -> {[VarName],State}. 457 458variable(#c_var{name=N}, Ps, St) -> 459 case is_element(N, Ps) of 460 true -> {[],add_error({duplicate_var,N,St#lint.func}, St)}; 461 false -> {[N],St} 462 end; 463variable(_, Def, St) -> {Def,add_error({not_var,St#lint.func}, St)}. 464 465%% variable_list([Var], State) -> {[Var],State}. 466%% variable_list([Var], [PatVar], State) -> {[Var],State}. 467 468variable_list(Vs, St) -> variable_list(Vs, [], St). 469 470variable_list(Vs, Ps, St) -> 471 foldl(fun (V, {Ps0,St0}) -> 472 {Vvs,St1} = variable(V, Ps0, St0), 473 {union(Vvs, Ps0),St1} 474 end, {Ps,St}, Vs). 475 476%% pattern(Pattern, Defined, State) -> {[PatVar],State}. 477%% pattern(Pattern, Defined, [PatVar], State) -> {[PatVar],State}. 478%% Patterns are complicated by sizes in binaries. These are pure 479%% input variables which create no bindings. We, therefore, need to 480%% carry around the original defined variables to get the correct 481%% handling. 482 483%% pattern(P, Def, St) -> pattern(P, Def, [], St). 484 485pattern(#c_var{name=N}, Def, Ps, St) -> 486 pat_var(N, Def, Ps, St); 487pattern(#c_literal{}, _Def, Ps, St) -> {Ps,St}; 488pattern(#c_cons{hd=H,tl=T}, Def, Ps, St) -> 489 pattern_list([H,T], Def, Ps, St); 490pattern(#c_tuple{es=Es}, Def, Ps, St) -> 491 pattern_list(Es, Def, Ps, St); 492pattern(#c_map{es=Es}, Def, Ps, St) -> 493 pattern_list(Es, Def, Ps, St); 494pattern(#c_map_pair{op=#c_literal{val=exact},key=K,val=V}, Def, Ps, St) -> 495 %% The key is an input. 496 pat_map_expr(K, Def, St), 497 pattern_list([V],Def,Ps,St); 498pattern(#c_binary{segments=Ss}, Def, Ps, St0) -> 499 St = pat_bin_tail_check(Ss, St0), 500 pat_bin(Ss, Def, Ps, St); 501pattern(#c_alias{var=V,pat=P}, Def, Ps, St0) -> 502 {Vvs,St1} = variable(V, Ps, St0), 503 pattern(P, Def, union(Vvs, Ps), St1); 504pattern(_Other, _, Ps, St) -> 505 %%io:fwrite("clint pattern: ~p~n", [_Other]), 506 {Ps,add_error({not_pattern,St#lint.func}, St)}. 507 508pat_var(N, _Def, Ps, St) -> 509 case is_element(N, Ps) of 510 true -> {Ps,add_error({duplicate_var,N,St#lint.func}, St)}; 511 false -> {add_element(N, Ps),St} 512 end. 513 514%% pat_bin_list([Elem], Defined, [PatVar], State) -> {[PatVar],State}. 515 516pat_bin(Es, Def0, Ps0, St0) -> 517 {Ps,_,St} = foldl(fun (E, {Ps,Def,St}) -> 518 pat_segment(E, Def, Ps, St) 519 end, {Ps0,Def0,St0}, Es), 520 {Ps,St}. 521 522pat_segment(#c_bitstr{val=V,size=S,type=T}, Def0, Ps0, St0) -> 523 St1 = pat_bit_expr(S, T, Def0, St0), 524 {Ps,St2} = pattern(V, Def0, Ps0, St1), 525 Def = case V of 526 #c_var{name=Name} -> add_element(Name, Def0); 527 _ -> Def0 528 end, 529 {Ps,Def,St2}; 530pat_segment(_, Def, Ps, St) -> 531 {Ps,Def,add_error({not_bs_pattern,St#lint.func}, St)}. 532 533%% pat_bin_tail_check([Elem], State) -> State. 534%% There must be at most one tail segment (a size-less segment of 535%% type binary) and it must occur at the end. 536 537pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}], St) -> 538 %% Size-less field is OK at the end of the list of segments. 539 St; 540pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}|_], St) -> 541 add_error({tail_segment_not_at_end,St#lint.func}, St); 542pat_bin_tail_check([_|Ss], St) -> 543 pat_bin_tail_check(Ss, St); 544pat_bin_tail_check([], St) -> St. 545 546%% pat_bit_expr(SizePat, Type, Defined, State) -> State. 547%% Check the Size pattern, this is an input! Because of optimizations, 548%% we must allow any kind of constant and literal here. 549 550pat_bit_expr(#c_var{name=N}, _, Def, St) -> expr_var(N, Def, St); 551pat_bit_expr(#c_literal{}, _, _, St) -> St; 552pat_bit_expr(#c_binary{}, _, _Def, St) -> 553 %% Literal binaries may be expressed as a bit syntax construction 554 %% expression if such expression is more compact than the literal. 555 %% Example: <<0:100000000>> 556 St; 557pat_bit_expr(_, _, _, St) -> 558 add_error({illegal_expr,St#lint.func}, St). 559 560pat_map_expr(#c_var{name=N}, Def, St) -> expr_var(N, Def, St); 561pat_map_expr(#c_literal{}, _Def, St) -> St; 562pat_map_expr(_, _, St) -> add_error({illegal_expr,St#lint.func}, St). 563 564%% pattern_list([Var], Defined, State) -> {[PatVar],State}. 565%% pattern_list([Var], Defined, [PatVar], State) -> {[PatVar],State}. 566 567pattern_list(Pats, Def, St) -> pattern_list(Pats, Def, [], St). 568 569pattern_list(Pats, Def, Ps0, St0) -> 570 foldl(fun (P, {Ps,St}) -> pattern(P, Def, Ps, St) end, {Ps0,St0}, Pats). 571 572%% pattern_match(Required, Supplied, State) -> State. 573%% Check that the required number of patterns match the supplied. 574 575pattern_match(N, N, St) -> St; 576pattern_match(_Req, _Sup, St) -> 577 add_error({pattern_mismatch,St#lint.func}, St). 578 579%% return_match(Required, Supplied, State) -> State. 580%% Check that the required number of return values match the supplied. 581 582return_match(any, _Sup, St) -> St; 583return_match(N, N, St) -> St; 584return_match(_Req, _Sup, St) -> 585 add_error({return_mismatch,St#lint.func}, St). 586 587%% arg_match(Required, Supplied, State) -> State. 588 589arg_match(N, N, St) -> St; 590arg_match(_Req, _Sup, St) -> 591 add_error({arg_mismatch,St#lint.func}, St). 592 593%% Only check if the top-level is a simple. 594-spec is_simple_top(cerl:cerl()) -> boolean(). 595 596is_simple_top(#c_var{}) -> true; 597is_simple_top(#c_cons{}) -> true; 598is_simple_top(#c_tuple{}) -> true; 599is_simple_top(#c_binary{}) -> true; 600is_simple_top(#c_literal{}) -> true; 601is_simple_top(_) -> false. 602