1
%% ``The contents of this file are subject to the Erlang Public License,
4
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
2
7
%% Version 1.1, (the "License"); you may not use this file except in
3
8
%% compliance with the License. You should have received a copy of the
4
9
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
10
%% retrieved online at http://www.erlang.org/.
7
12
%% Software distributed under the License is distributed on an "AS IS"
8
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
14
%% the License for the specific language governing rights and limitations
10
15
%% under the License.
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
18
19
%% Purpose : Do necessary checking of Core Erlang code.
242
243
evars=[#c_var{},#c_var{}],handler=#c_literal{val=false}},
244
245
gbody(E, Def, Rt, St);
245
gexpr(Core, _, _, St) ->
246
gexpr(#c_case{arg=Arg,clauses=Cs}, Def, Rt, St0) ->
247
PatCount = case_patcount(Cs),
248
St1 = gbody(Arg, Def, PatCount, St0),
249
clauses(Cs, Def, PatCount, Rt, St1);
250
gexpr(_Core, _, _, St) ->
246
251
add_error({illegal_guard,St#lint.func}, St).
248
253
%% gexpr_list([Expr], Defined, State) -> State.
255
260
gbitstr_list(Es, Def, St0) ->
256
261
foldl(fun (E, St) -> gbitstr(E, Def, St) end, St0, Es).
258
gbitstr(#c_bitstr{val=V,size=S,unit=U,type=T,flags=Fs}, Def, St0) ->
259
St1 = bit_type(U, T, Fs, St0),
260
gexpr_list([V,S], Def, St1).
263
gbitstr(#c_bitstr{val=V,size=S}, Def, St) ->
264
gexpr_list([V,S], Def, St).
262
266
%% expr(Expr, Defined, RetCount, State) -> State.
268
expr(#c_var{name={_,_}=FA}, Def, _Rt, St) ->
269
expr_fname(FA, Def, St);
264
270
expr(#c_var{name=N}, Def, _Rt, St) -> expr_var(N, Def, St);
265
271
expr(#c_literal{}, _Def, _Rt, St) -> St;
266
272
expr(#c_cons{hd=H,tl=T}, Def, _Rt, St) ->
269
275
expr_list(Es, Def, St);
270
276
expr(#c_binary{segments=Ss}, Def, _Rt, St) ->
271
277
bitstr_list(Ss, Def, St);
272
expr(#c_fname{id=I,arity=A}, Def, _Rt, St) ->
273
expr_fname({I,A}, Def, St);
274
278
expr(#c_fun{vars=Vs,body=B}, Def, Rt, St0) ->
275
279
{Vvs,St1} = variable_list(Vs, St0),
276
280
return_match(Rt, 1, body(B, union(Vvs, Def), any, St1));
289
293
Pc = case_patcount(Cs),
290
294
St1 = body(Arg, Def, Pc, St0),
291
295
clauses(Cs, Def, Pc, Rt, St1);
296
expr(#c_receive{clauses=Cs,timeout=#c_literal{val=infinity},
297
action=#c_literal{}},
299
%% If the timeout is 'infinity', the after code can never
300
%% be reached. We don't care if the return count is wrong.
301
clauses(Cs, Def, 1, Rt, St);
292
302
expr(#c_receive{clauses=Cs,timeout=T,action=A}, Def, Rt, St0) ->
293
303
St1 = expr(T, Def, 1, St0),
294
304
St2 = body(A, Def, Rt, St1),
314
324
St4 = body(B, union(Ns, Def), Rt, St3),
315
325
{Ens,St5} = variable_list(Evs, St4),
316
326
body(H, union(Ens, Def), Rt, St5);
318
%%io:fwrite("clint: ~p~n", [Other]),
327
expr(_Other, _, _, St) ->
328
%%io:fwrite("clint: ~p~n", [_Other]),
319
329
add_error({illegal_expr,St#lint.func}, St).
321
331
%% expr_list([Expr], Defined, State) -> State.
328
338
bitstr_list(Es, Def, St0) ->
329
339
foldl(fun (E, St) -> bitstr(E, Def, St) end, St0, Es).
331
bitstr(#c_bitstr{val=V,size=S,unit=U,type=T,flags=Fs}, Def, St0) ->
332
St1 = bit_type(U, T, Fs, St0),
333
expr_list([V,S], Def, St1).
341
bitstr(#c_bitstr{val=V,size=S}, Def, St) ->
342
expr_list([V,S], Def, St).
335
344
%% apply_op(Op, Defined, ArgCount, State) -> State.
336
345
%% A apply op is either an fname or an expression.
338
apply_op(#c_fname{id=I,arity=A}, Def, Ac, St0) ->
347
apply_op(#c_var{name={I,A}}, Def, Ac, St0) ->
339
348
St1 = expr_fname({I,A}, Def, St0),
340
349
arg_match(Ac, A, St1);
341
350
apply_op(E, Def, _, St) -> expr(E, Def, 1, St). %Hard to check
431
440
%% pat_bin_list([Elem], Defined, [PatVar], State) -> {[PatVar],State}.
433
pat_bin(Es, Def, Ps0, St0) ->
434
foldl(fun (E, {Ps,St}) -> pat_segment(E, Def, Ps, St) end, {Ps0,St0}, Es).
442
pat_bin(Es, Def0, Ps0, St0) ->
443
{Ps,_,St} = foldl(fun (E, {Ps,Def,St}) ->
444
pat_segment(E, Def, Ps, St)
445
end, {Ps0,Def0,St0}, Es),
436
pat_segment(#c_bitstr{val=V,size=S,unit=U,type=T,flags=Fs}, Def, Ps, St0) ->
437
St1 = bit_type(U, T, Fs, St0),
438
St2 = pat_bit_expr(S, T, Def, St1),
439
pattern(V, Def, Ps, St2);
440
pat_segment(_, _, Ps, St) ->
441
{Ps,add_error({not_bs_pattern,St#lint.func}, St)}.
448
pat_segment(#c_bitstr{val=V,size=S,type=T}, Def0, Ps0, St0) ->
449
St1 = pat_bit_expr(S, T, Def0, St0),
450
{Ps,St2} = pattern(V, Def0, Ps0, St1),
452
#c_var{name=Name} -> add_element(Name, Def0);
456
pat_segment(_, Def, Ps, St) ->
457
{Ps,Def,add_error({not_bs_pattern,St#lint.func}, St)}.
443
459
%% pat_bit_expr(SizePat, Type, Defined, State) -> State.
444
%% Check the Size pattern, this is an input! Be a bit tough here.
460
%% Check the Size pattern, this is an input! Because of optimizations,
461
%% we must allow any kind of constant and literal here.
446
pat_bit_expr(#c_literal{val=I}, _, _, St) when is_integer(I), I >= 0 -> St;
447
pat_bit_expr(#c_var{name=N}, _, Def, St) ->
448
expr_var(N, Def, St);
449
pat_bit_expr(#c_literal{val=all}, #c_literal{val=binary}, _Def, St) -> St;
463
pat_bit_expr(#c_var{name=N}, _, Def, St) -> expr_var(N, Def, St);
464
pat_bit_expr(#c_literal{}, _, _, St) -> St;
465
pat_bit_expr(#c_binary{}, _, _Def, St) ->
466
%% Literal binaries may be expressed as a bit syntax construction
467
%% expression if such expression is more compact than the literal.
468
%% Example: <<0:100000000>>
450
470
pat_bit_expr(_, _, _, St) ->
451
471
add_error({illegal_expr,St#lint.func}, St).
453
bit_type(Unit, Type, Flags, St) ->
454
U = core_lib:literal_value(Unit),
455
T = core_lib:literal_value(Type),
456
Fs = core_lib:literal_value(Flags),
457
case erl_bits:set_bit_type(default, [T,{unit,U}|Fs]) of
459
{error,E} -> add_error({E,St#lint.func}, St)
462
473
%% pattern_list([Var], Defined, State) -> {[PatVar],State}.
463
474
%% pattern_list([Var], Defined, [PatVar], State) -> {[PatVar],State}.