~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/compiler/src/core_lint.erl

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-05-07 15:07:37 UTC
  • mfrom: (1.2.1 upstream) (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090507150737-i4yb5elwinm7r0hc
Tags: 1:13.b-dfsg1-1
* Removed another bunch of non-free RFCs from original tarball
  (closes: #527053).
* Fixed build-dependencies list by adding missing comma. This requires
  libsctp-dev again. Also, added libsctp1 dependency to erlang-base and
  erlang-base-hipe packages because the shared library is loaded via
  dlopen now and cannot be added using dh_slibdeps (closes: #526682).
* Weakened dependency of erlang-webtool on erlang-observer to recommends
  to avoid circular dependencies (closes: #526627).
* Added solaris-i386 to HiPE enabled architectures.
* Made script sources in /usr/lib/erlang/erts-*/bin directory executable,
  which is more convenient if a user wants to create a target Erlang system.
* Shortened extended description line for erlang-dev package to make it
  fit 80x25 terminals.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
%% ``The contents of this file are subject to the Erlang Public License,
 
1
%%
 
2
%% %CopyrightBegin%
 
3
%% 
 
4
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
 
5
%% 
 
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/.
6
11
%% 
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.
11
16
%% 
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.''
15
 
%% 
16
 
%%     $Id$
 
17
%% %CopyrightEnd%
17
18
%%
18
19
%% Purpose : Do necessary checking of Core Erlang code.
19
20
 
112
113
%% defined_funcs([FuncDef]) -> [Fname].
113
114
 
114
115
defined_funcs(Fs) ->
115
 
    foldl(fun ({#c_fname{id=I,arity=A},_}, Def) ->
 
116
    foldl(fun ({#c_var{name={I,A}},_}, Def) ->
116
117
                  add_element({I,A}, Def)
117
118
          end, [], Fs).
118
119
 
136
137
%%add_warning(W, St) -> St#lint{warnings=[{none,core_lint,W}|St#lint.warnings]}.
137
138
 
138
139
check_exports(Es, St) ->
139
 
    case all(fun (#c_fname{id=Name,arity=Arity})
 
140
    case all(fun (#c_var{name={Name,Arity}})
140
141
                 when is_atom(Name), is_integer(Arity) -> true;
141
142
                 (_) -> false
142
143
             end, Es) of
153
154
    end.
154
155
 
155
156
check_state(Es, Defined, St) ->
156
 
    foldl(fun (#c_fname{id=N,arity=A}, St1) ->
 
157
    foldl(fun (#c_var{name={N,A}}, St1) ->
157
158
                  F = {N,A},
158
159
                  case is_element(F, Defined) of
159
160
                      true -> St1;
166
167
module_defs(B, Def, St) ->
167
168
    %% Set top level function name.
168
169
    foldl(fun (Func, St0) ->
169
 
                  {#c_fname{id=F,arity=A},_} = Func,
 
170
                  {#c_var{name={F,A}},_} = Func,
170
171
                  St1 = St0#lint{func={F,A}},
171
172
                  function(Func, Def, St1)
172
173
          end, St, B).
178
179
 
179
180
%% function(CoreFunc, Defined, State) -> State.
180
181
 
181
 
function({#c_fname{},B}, Def, St) ->
 
182
function({#c_var{name={_,_}},B}, Def, St) ->
182
183
    %% Body must be a fun!
183
184
    case B of
184
185
        #c_fun{} -> expr(B, Def, any, St);
242
243
             evars=[#c_var{},#c_var{}],handler=#c_literal{val=false}},
243
244
      Def, Rt, St) ->
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).
247
252
 
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).
257
262
 
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).
261
265
 
262
266
%% expr(Expr, Defined, RetCount, State) -> State.
263
267
 
 
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{}},
 
298
     Def, Rt, St) ->
 
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);
317
 
expr(_, _, _, St) ->
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).
320
330
 
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).
330
340
 
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).
334
343
 
335
344
%% apply_op(Op, Defined, ArgCount, State) -> State.
336
345
%%  A apply op is either an fname or an expression.
337
346
 
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
402
411
%% pattern(Pattern, Defined, State) -> {[PatVar],State}.
403
412
%% pattern(Pattern, Defined, [PatVar], State) -> {[PatVar],State}.
404
413
%%  Patterns are complicated by sizes in binaries.  These are pure
405
 
%%  input variables which create no bindings.  We, therefor, need to
 
414
%%  input variables which create no bindings.  We, therefore, need to
406
415
%%  carry around the original defined variables to get the correct
407
416
%%  handling.
408
417
 
430
439
 
431
440
%% pat_bin_list([Elem], Defined, [PatVar], State) -> {[PatVar],State}.
432
441
 
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),
 
446
    {Ps,St}.
435
447
 
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),
 
451
    Def = case V of
 
452
              #c_var{name=Name} -> add_element(Name, Def0);
 
453
              _ -> Def0
 
454
          end,
 
455
    {Ps,Def,St2};
 
456
pat_segment(_, Def, Ps, St) ->
 
457
    {Ps,Def,add_error({not_bs_pattern,St#lint.func}, St)}.
442
458
 
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.
445
462
 
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>>
 
469
    St;
450
470
pat_bit_expr(_, _, _, St) ->
451
471
    add_error({illegal_expr,St#lint.func}, St).
452
472
 
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
458
 
        {ok,_,_} -> St;
459
 
        {error,E} -> add_error({E,St#lint.func}, St)
460
 
    end.
461
 
 
462
473
%% pattern_list([Var], Defined, State) -> {[PatVar],State}.
463
474
%% pattern_list([Var], Defined, [PatVar], State) -> {[PatVar],State}.
464
475
 
484
495
 
485
496
%% arg_match(Required, Supplied, State) -> State.
486
497
 
487
 
arg_match(_Req, unknown, St) -> St;
488
498
arg_match(N, N, St) -> St;
489
499
arg_match(_Req, _Sup, St) ->
490
500
    add_error({arg_mismatch,St#lint.func}, St).