1%%% -*- erlang-indent-level: 4 -*-
2%%
3%% %CopyrightBegin%
4%%
5%% Copyright Ericsson AB 1996-2020. All Rights Reserved.
6%%
7%% Licensed under the Apache License, Version 2.0 (the "License");
8%% you may not use this file except in compliance with the License.
9%% You may obtain a copy of the License at
10%%
11%%     http://www.apache.org/licenses/LICENSE-2.0
12%%
13%% Unless required by applicable law or agreed to in writing, software
14%% distributed under the License is distributed on an "AS IS" BASIS,
15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16%% See the License for the specific language governing permissions and
17%% limitations under the License.
18%%
19%% %CopyrightEnd%
20%%
21%% Do necessary checking of Erlang code.
22
23-module(erl_lint).
24
25-export([module/1,module/2,module/3,format_error/1]).
26-export([exprs/2,exprs_opt/3,used_vars/2]). % Used from erl_eval.erl.
27-export([is_pattern_expr/1,is_guard_test/1,is_guard_test/2,is_guard_test/3]).
28-export([is_guard_expr/1]).
29-export([bool_option/4,value_option/3,value_option/7]).
30
31-import(lists, [all/2,any/2,
32                foldl/3,foldr/3,
33                map/2,mapfoldl/3,member/2,
34                reverse/1]).
35
36%% Removed functions
37
38-removed([{modify_line,2,"use erl_parse:map_anno/2 instead"}]).
39
40%% bool_option(OnOpt, OffOpt, Default, Options) -> boolean().
41%% value_option(Flag, Default, Options) -> Value.
42%% value_option(Flag, Default, OnOpt, OnVal, OffOpt, OffVal, Options) ->
43%%              Value.
44%%  The option handling functions.
45
46-spec bool_option(atom(), atom(), boolean(), [compile:option()]) -> boolean().
47
48bool_option(On, Off, Default, Opts) ->
49    foldl(fun (Opt, _Def) when Opt =:= On -> true;
50              (Opt, _Def) when Opt =:= Off -> false;
51              (_Opt, Def) -> Def
52          end, Default, Opts).
53
54value_option(Flag, Default, Opts) ->
55    foldl(fun ({Opt,Val}, _Def) when Opt =:= Flag -> Val;
56              (_Opt, Def) -> Def
57          end, Default, Opts).
58
59value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
60    foldl(fun ({Opt,Val}, _Def) when Opt =:= Flag -> Val;
61              (Opt, _Def) when Opt =:= On -> OnVal;
62              (Opt, _Def) when Opt =:= Off -> OffVal;
63              (_Opt, Def) -> Def
64          end, Default, Opts).
65
66%% The maximum number of arguments allowed for a function.
67
68-define(MAX_ARGUMENTS, 255).
69
70%% The error and warning info structures, {Line,Module,Descriptor},
71%% are kept in their seperate fields in the lint state record together
72%% with the name of the file (when a new file is entered, marked by
73%% the 'file' attribute, then the field 'file' of the lint record is
74%% set). At the end of the run these lists are packed into a list of
75%% {FileName,ErrorDescList} pairs which are returned.
76
77-include_lib("stdlib/include/erl_bits.hrl").
78
79%%-define(DEBUGF(X,Y), io:format(X, Y)).
80-define(DEBUGF(X,Y), void).
81
82-type line() :: erl_anno:anno().     % a convenient alias
83-type fa()   :: {atom(), arity()}.   % function+arity
84-type ta()   :: {atom(), arity()}.   % type+arity
85
86-type module_or_mfa() :: module() | mfa().
87
88-type gexpr_context() :: 'guard' | 'bin_seg_size' | 'map_key'.
89
90-record(typeinfo, {attr, line}).
91
92%% Usage of records, functions, and imports. The variable table, which
93%% is passed on as an argument, holds the usage of variables.
94-record(usage, {
95          calls = maps:new(),			%Who calls who
96          imported = [],                        %Actually imported functions
97          used_records = gb_sets:new()          %Used record definitions
98              :: gb_sets:set(atom()),
99          used_types = maps:new()               %Used type definitions
100              :: #{ta() := line()}
101         }).
102
103
104%% Define the lint state record.
105%% 'called' and 'exports' contain {Line, {Function, Arity}},
106%% the other function collections contain {Function, Arity}.
107-record(lint, {state=start		:: 'start' | 'attribute' | 'function',
108               module='',                       %Module
109               behaviour=[],                    %Behaviour
110               exports=gb_sets:empty()	:: gb_sets:set(fa()),%Exports
111               imports=[] :: orddict:orddict(fa(), module()),%Imports
112               compile=[],                      %Compile flags
113               records=maps:new()               %Record definitions
114                   :: #{atom() => {line(),Fields :: term()}},
115               locals=gb_sets:empty()     %All defined functions (prescanned)
116                   :: gb_sets:set(fa()),
117               no_auto=gb_sets:empty() %Functions explicitly not autoimported
118                   :: gb_sets:set(fa()) | 'all',
119               defined=gb_sets:empty()          %Defined fuctions
120                   :: gb_sets:set(fa()),
121	       on_load=[] :: [fa()],		%On-load function
122	       on_load_line=erl_anno:new(0)	%Line for on_load
123                   :: erl_anno:anno(),
124	       clashes=[],			%Exported functions named as BIFs
125               not_deprecated=[],               %Not considered deprecated
126               not_removed=gb_sets:empty()      %Not considered removed
127                   :: gb_sets:set(module_or_mfa()),
128               func=[],                         %Current function
129               warn_format=0,                   %Warn format calls
130	       enabled_warnings=[],		%All enabled warnings (ordset).
131               nowarn_bif_clash=[],             %All no warn bif clashes (ordset).
132               errors=[],                       %Current errors
133               warnings=[],                     %Current warnings
134               file = ""        :: string(),	%From last file attribute
135               recdef_top=false :: boolean(),	%true in record initialisation
136						%outside any fun or lc
137               xqlc= false :: boolean(),	%true if qlc.hrl included
138               called= [] :: [{fa(),line()}],   %Called functions
139               usage = #usage{}		:: #usage{},
140               specs = maps:new()               %Type specifications
141                   :: #{mfa() => line()},
142               callbacks = maps:new()           %Callback types
143                   :: #{mfa() => line()},
144               optional_callbacks = maps:new()  %Optional callbacks
145                   :: #{mfa() => line()},
146               types = maps:new()               %Type definitions
147                   :: #{ta() => #typeinfo{}},
148               exp_types=gb_sets:empty()        %Exported types
149                   :: gb_sets:set(ta()),
150               in_try_head=false :: boolean(),  %In a try head.
151               bvt = none :: 'none' | [any()],  %Variables in binary pattern
152               gexpr_context = guard            %Context of guard expression
153                   :: gexpr_context()
154              }).
155
156-type lint_state() :: #lint{}.
157-type error_description() :: term().
158-type error_info() :: {erl_anno:line(), module(), error_description()}.
159
160%% format_error(Error)
161%%  Return a string describing the error.
162
163-spec format_error(ErrorDescriptor) -> io_lib:chars() when
164      ErrorDescriptor :: error_description().
165
166format_error(undefined_module) ->
167    "no module definition";
168format_error(redefine_module) ->
169    "redefining module";
170format_error(pmod_unsupported) ->
171    "parameterized modules are no longer supported";
172%% format_error({redefine_mod_import, M, P}) ->
173%%     io_lib:format("module '~s' already imported from package '~s'", [M, P]);
174format_error(non_latin1_module_unsupported) ->
175    "module names with non-latin1 characters are not supported";
176
177format_error(invalid_call) ->
178    "invalid function call";
179format_error(invalid_record) ->
180    "invalid record expression";
181
182format_error({attribute,A}) ->
183    io_lib:format("attribute ~tw after function definitions", [A]);
184format_error({missing_qlc_hrl,A}) ->
185    io_lib:format("qlc:q/~w called, but \"qlc.hrl\" not included", [A]);
186format_error({redefine_import,{{F,A},M}}) ->
187    io_lib:format("function ~tw/~w already imported from ~w", [F,A,M]);
188format_error({bad_inline,{F,A}}) ->
189    io_lib:format("inlined function ~tw/~w undefined", [F,A]);
190format_error({invalid_deprecated,D}) ->
191    io_lib:format("badly formed deprecated attribute ~tw", [D]);
192format_error({bad_deprecated,{F,A}}) ->
193    io_lib:format("deprecated function ~tw/~w undefined or not exported",
194                  [F,A]);
195format_error({invalid_removed,D}) ->
196    io_lib:format("badly formed removed attribute ~tw", [D]);
197format_error({bad_removed,{F,A}}) when F =:= '_'; A =:= '_' ->
198    io_lib:format("at least one function matching ~tw/~w is still exported",
199                  [F,A]);
200format_error({bad_removed,{F,A}}) ->
201    io_lib:format("removed function ~tw/~w is still exported",
202                  [F,A]);
203format_error({bad_nowarn_unused_function,{F,A}}) ->
204    io_lib:format("function ~tw/~w undefined", [F,A]);
205format_error({bad_nowarn_bif_clash,{F,A}}) ->
206    io_lib:format("function ~tw/~w undefined", [F,A]);
207format_error(disallowed_nowarn_bif_clash) ->
208    io_lib:format("compile directive nowarn_bif_clash is no longer allowed,~n"
209		  " - use explicit module names or -compile({no_auto_import, [F/A]})", []);
210format_error({bad_on_load,Term}) ->
211    io_lib:format("badly formed on_load attribute: ~tw", [Term]);
212format_error(multiple_on_loads) ->
213    "more than one on_load attribute";
214format_error({bad_on_load_arity,{F,A}}) ->
215    io_lib:format("function ~tw/~w has wrong arity (must be 0)", [F,A]);
216format_error({undefined_on_load,{F,A}}) ->
217    io_lib:format("function ~tw/~w undefined", [F,A]);
218format_error(nif_inline) ->
219    "inlining is enabled - local calls to NIFs may call their Erlang "
220    "implementation instead";
221
222format_error(export_all) ->
223    "export_all flag enabled - all functions will be exported";
224format_error({duplicated_export, {F,A}}) ->
225    io_lib:format("function ~tw/~w already exported", [F,A]);
226format_error({unused_import,{{F,A},M}}) ->
227    io_lib:format("import ~w:~tw/~w is unused", [M,F,A]);
228format_error({undefined_function,{F,A}}) ->
229    io_lib:format("function ~tw/~w undefined", [F,A]);
230format_error({redefine_function,{F,A}}) ->
231    io_lib:format("function ~tw/~w already defined", [F,A]);
232format_error({define_import,{F,A}}) ->
233    io_lib:format("defining imported function ~tw/~w", [F,A]);
234format_error({unused_function,{F,A}}) ->
235    io_lib:format("function ~tw/~w is unused", [F,A]);
236format_error({call_to_redefined_bif,{F,A}}) ->
237    io_lib:format("ambiguous call of overridden auto-imported BIF ~w/~w~n"
238		  " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" "
239		  "to resolve name clash", [F,A,F,A,F,A]);
240format_error({call_to_redefined_old_bif,{F,A}}) ->
241    io_lib:format("ambiguous call of overridden pre R14 auto-imported BIF ~w/~w~n"
242		  " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" "
243		  "to resolve name clash", [F,A,F,A,F,A]);
244format_error({redefine_old_bif_import,{F,A}}) ->
245    io_lib:format("import directive overrides pre R14 auto-imported BIF ~w/~w~n"
246		  " - use \"-compile({no_auto_import,[~w/~w]}).\" "
247		  "to resolve name clash", [F,A,F,A]);
248format_error({redefine_bif_import,{F,A}}) ->
249    io_lib:format("import directive overrides auto-imported BIF ~w/~w~n"
250		  " - use \"-compile({no_auto_import,[~w/~w]}).\" to resolve name clash", [F,A,F,A]);
251format_error({deprecated, MFA, String, Rel}) ->
252    io_lib:format("~s is deprecated and will be removed in ~s; use ~s",
253		  [format_mfa(MFA), Rel, String]);
254format_error({deprecated, MFA, String}) when is_list(String) ->
255    io_lib:format("~s is deprecated; ~s", [format_mfa(MFA), String]);
256format_error({deprecated_type, {M1, F1, A1}, String}) when is_list(String) ->
257    io_lib:format("the type ~p:~p~s is deprecated; ~s",
258                  [M1, F1, gen_type_paren(A1), String]);
259format_error({removed, MFA, ReplacementMFA, Rel}) ->
260    io_lib:format("call to ~s will fail, since it was removed in ~s; "
261		  "use ~s", [format_mfa(MFA), Rel, format_mfa(ReplacementMFA)]);
262format_error({removed, MFA, String}) when is_list(String) ->
263    io_lib:format("~s is removed; ~s", [format_mfa(MFA), String]);
264format_error({removed_type, MNA, String}) ->
265    io_lib:format("the type ~s is removed; ~s", [format_mna(MNA), String]);
266format_error({obsolete_guard, {F, A}}) ->
267    io_lib:format("~p/~p obsolete (use is_~p/~p)", [F, A, F, A]);
268format_error({obsolete_guard_overridden,Test}) ->
269    io_lib:format("obsolete ~s/1 (meaning is_~s/1) is illegal when "
270		  "there is a local/imported function named is_~p/1 ",
271		  [Test,Test,Test]);
272format_error({too_many_arguments,Arity}) ->
273    io_lib:format("too many arguments (~w) - "
274		  "maximum allowed is ~w", [Arity,?MAX_ARGUMENTS]);
275%% --- patterns and guards ---
276format_error(illegal_pattern) -> "illegal pattern";
277format_error(illegal_map_key) -> "illegal map key in pattern";
278format_error(illegal_bin_pattern) ->
279    "binary patterns cannot be matched in parallel using '='";
280format_error(illegal_expr) -> "illegal expression";
281format_error({illegal_guard_local_call, {F,A}}) ->
282    io_lib:format("call to local/imported function ~tw/~w is illegal in guard",
283		  [F,A]);
284format_error(illegal_guard_expr) -> "illegal guard expression";
285%% --- maps ---
286format_error(illegal_map_construction) ->
287    "only association operators '=>' are allowed in map construction";
288%% --- records ---
289format_error({undefined_record,T}) ->
290    io_lib:format("record ~tw undefined", [T]);
291format_error({redefine_record,T}) ->
292    io_lib:format("record ~tw already defined", [T]);
293format_error({redefine_field,T,F}) ->
294    io_lib:format("field ~tw already defined in record ~tw", [F,T]);
295format_error(bad_multi_field_init) ->
296    io_lib:format("'_' initializes no omitted fields", []);
297format_error({undefined_field,T,F}) ->
298    io_lib:format("field ~tw undefined in record ~tw", [F,T]);
299format_error(illegal_record_info) ->
300    "illegal record info";
301format_error({field_name_is_variable,T,F}) ->
302    io_lib:format("field ~tw is not an atom or _ in record ~tw", [F,T]);
303format_error({wildcard_in_update,T}) ->
304    io_lib:format("meaningless use of _ in update of record ~tw", [T]);
305format_error({unused_record,T}) ->
306    io_lib:format("record ~tw is unused", [T]);
307format_error({untyped_record,T}) ->
308    io_lib:format("record ~tw has field(s) without type information", [T]);
309%% --- variables ----
310format_error({unbound_var,V}) ->
311    io_lib:format("variable ~w is unbound", [V]);
312format_error({unsafe_var,V,{What,Where}}) ->
313    io_lib:format("variable ~w unsafe in ~w ~s",
314                  [V,What,format_where(Where)]);
315format_error({exported_var,V,{What,Where}}) ->
316    io_lib:format("variable ~w exported from ~w ~s",
317                  [V,What,format_where(Where)]);
318format_error({shadowed_var,V,In}) ->
319    io_lib:format("variable ~w shadowed in ~w", [V,In]);
320format_error({unused_var, V}) ->
321    io_lib:format("variable ~w is unused", [V]);
322format_error({variable_in_record_def,V}) ->
323    io_lib:format("variable ~w in record definition", [V]);
324format_error({stacktrace_guard,V}) ->
325    io_lib:format("stacktrace variable ~w must not be used in a guard", [V]);
326format_error({stacktrace_bound,V}) ->
327    io_lib:format("stacktrace variable ~w must not be previously bound", [V]);
328%% --- binaries ---
329format_error({undefined_bittype,Type}) ->
330    io_lib:format("bit type ~tw undefined", [Type]);
331format_error({bittype_mismatch,Val1,Val2,What}) ->
332    io_lib:format("conflict in ~s specification for bit field: '~p' and '~p'",
333		  [What,Val1,Val2]);
334format_error(bittype_unit) ->
335    "a bit unit size must not be specified unless a size is specified too";
336format_error(illegal_bitsize) ->
337    "illegal bit size";
338format_error({illegal_bitsize_local_call, {F,A}}) ->
339    io_lib:format("call to local/imported function ~tw/~w is illegal in a size "
340                  "expression for a binary segment",
341		  [F,A]);
342format_error(non_integer_bitsize) ->
343    "a size expression in a pattern evaluates to a non-integer value; "
344        "this pattern cannot possibly match";
345format_error(unsized_binary_not_at_end) ->
346    "a binary field without size is only allowed at the end of a binary pattern";
347format_error(typed_literal_string) ->
348    "a literal string in a binary pattern must not have a type or a size";
349format_error(utf_bittype_size_or_unit) ->
350    "neither size nor unit must be given for segments of type utf8/utf16/utf32";
351format_error({bad_bitsize,Type}) ->
352    io_lib:format("bad ~s bit size", [Type]);
353format_error(unsized_binary_in_bin_gen_pattern) ->
354    "binary fields without size are not allowed in patterns of bit string generators";
355%% --- behaviours ---
356format_error({conflicting_behaviours,{Name,Arity},B,FirstL,FirstB}) ->
357    io_lib:format("conflicting behaviours - callback ~tw/~w required by both '~p' "
358		  "and '~p' ~s", [Name,Arity,B,FirstB,format_where(FirstL)]);
359format_error({undefined_behaviour_func, {Func,Arity}, Behaviour}) ->
360    io_lib:format("undefined callback function ~tw/~w (behaviour '~w')",
361		  [Func,Arity,Behaviour]);
362format_error({undefined_behaviour,Behaviour}) ->
363    io_lib:format("behaviour ~tw undefined", [Behaviour]);
364format_error({undefined_behaviour_callbacks,Behaviour}) ->
365    io_lib:format("behaviour ~w callback functions are undefined",
366		  [Behaviour]);
367format_error({ill_defined_behaviour_callbacks,Behaviour}) ->
368    io_lib:format("behaviour ~w callback functions erroneously defined",
369		  [Behaviour]);
370format_error({ill_defined_optional_callbacks,Behaviour}) ->
371    io_lib:format("behaviour ~w optional callback functions erroneously defined",
372		  [Behaviour]);
373format_error({behaviour_info, {_M,F,A}}) ->
374    io_lib:format("cannot define callback attibute for ~tw/~w when "
375                  "behaviour_info is defined",[F,A]);
376format_error({redefine_optional_callback, {F, A}}) ->
377    io_lib:format("optional callback ~tw/~w duplicated", [F, A]);
378format_error({undefined_callback, {_M, F, A}}) ->
379    io_lib:format("callback ~tw/~w is undefined", [F, A]);
380%% --- types and specs ---
381format_error({singleton_typevar, Name}) ->
382    io_lib:format("type variable ~w is only used once (is unbound)", [Name]);
383format_error({bad_export_type, _ETs}) ->
384    io_lib:format("bad export_type declaration", []);
385format_error({duplicated_export_type, {T, A}}) ->
386    io_lib:format("type ~tw/~w already exported", [T, A]);
387format_error({undefined_type, {TypeName, Arity}}) ->
388    io_lib:format("type ~tw~s undefined", [TypeName, gen_type_paren(Arity)]);
389format_error({unused_type, {TypeName, Arity}}) ->
390    io_lib:format("type ~tw~s is unused", [TypeName, gen_type_paren(Arity)]);
391format_error({new_builtin_type, {TypeName, Arity}}) ->
392    io_lib:format("type ~w~s is a new builtin type; "
393		  "its (re)definition is allowed only until the next release",
394		  [TypeName, gen_type_paren(Arity)]);
395format_error({builtin_type, {TypeName, Arity}}) ->
396    io_lib:format("type ~w~s is a builtin type; it cannot be redefined",
397		  [TypeName, gen_type_paren(Arity)]);
398format_error({renamed_type, OldName, NewName}) ->
399    io_lib:format("type ~w() is now called ~w(); "
400		  "please use the new name instead", [OldName, NewName]);
401format_error({redefine_type, {TypeName, Arity}}) ->
402    io_lib:format("type ~tw~s already defined",
403		  [TypeName, gen_type_paren(Arity)]);
404format_error({type_syntax, Constr}) ->
405    io_lib:format("bad ~tw type", [Constr]);
406format_error(old_abstract_code) ->
407    io_lib:format("abstract code generated before Erlang/OTP 19.0 and "
408                  "having typed record fields cannot be compiled", []);
409format_error({redefine_spec, {M, F, A}}) ->
410    io_lib:format("spec for ~tw:~tw/~w already defined", [M, F, A]);
411format_error({redefine_spec, {F, A}}) ->
412    io_lib:format("spec for ~tw/~w already defined", [F, A]);
413format_error({redefine_callback, {F, A}}) ->
414    io_lib:format("callback ~tw/~w already defined", [F, A]);
415format_error({bad_callback, {M, F, A}}) ->
416    io_lib:format("explicit module not allowed for callback ~tw:~tw/~w",
417                  [M, F, A]);
418format_error({bad_module, {M, F, A}}) ->
419    io_lib:format("spec for function ~w:~tw/~w from other module", [M, F, A]);
420format_error({spec_fun_undefined, {F, A}}) ->
421    io_lib:format("spec for undefined function ~tw/~w", [F, A]);
422format_error({missing_spec, {F,A}}) ->
423    io_lib:format("missing specification for function ~tw/~w", [F, A]);
424format_error(spec_wrong_arity) ->
425    "spec has wrong arity";
426format_error(callback_wrong_arity) ->
427    "callback has wrong arity";
428format_error({deprecated_builtin_type, {Name, Arity},
429              Replacement, Rel}) ->
430    UseS = case Replacement of
431               {Mod, NewName} ->
432                   io_lib:format("use ~w:~w/~w", [Mod, NewName, Arity]);
433               {Mod, NewName, NewArity} ->
434                   io_lib:format("use ~w:~w/~w or preferably ~w:~w/~w",
435                                 [Mod, NewName, Arity,
436                                  Mod, NewName, NewArity])
437           end,
438    io_lib:format("type ~w/~w is deprecated and will be "
439                  "removed in ~s; use ~s",
440                  [Name, Arity, Rel, UseS]);
441format_error({not_exported_opaque, {TypeName, Arity}}) ->
442    io_lib:format("opaque type ~tw~s is not exported",
443                  [TypeName, gen_type_paren(Arity)]);
444format_error({underspecified_opaque, {TypeName, Arity}}) ->
445    io_lib:format("opaque type ~tw~s is underspecified and therefore meaningless",
446                  [TypeName, gen_type_paren(Arity)]);
447format_error({bad_dialyzer_attribute,Term}) ->
448    io_lib:format("badly formed dialyzer attribute: ~tw", [Term]);
449format_error({bad_dialyzer_option,Term}) ->
450    io_lib:format("unknown dialyzer warning option: ~tw", [Term]);
451%% --- obsolete? unused? ---
452format_error({format_error, {Fmt, Args}}) ->
453    io_lib:format(Fmt, Args).
454
455gen_type_paren(Arity) when is_integer(Arity), Arity >= 0 ->
456    gen_type_paren_1(Arity, ")").
457
458gen_type_paren_1(0, Acc) -> "(" ++ Acc;
459gen_type_paren_1(1, Acc) -> "(_" ++ Acc;
460gen_type_paren_1(N, Acc) -> gen_type_paren_1(N - 1, ",_" ++ Acc).
461
462format_mfa({M, F, [_|_]=As}) ->
463    ","++ArityString = lists:append([[$,|integer_to_list(A)] || A <- As]),
464    format_mf(M, F, ArityString);
465format_mfa({M, F, A}) when is_integer(A) ->
466    format_mf(M, F, integer_to_list(A)).
467
468format_mf(M, F, ArityString) when is_atom(M), is_atom(F) ->
469    atom_to_list(M) ++ ":" ++ atom_to_list(F) ++ "/" ++ ArityString.
470
471format_mna({M, N, A}) when is_integer(A) ->
472    atom_to_list(M) ++ ":" ++ atom_to_list(N) ++ gen_type_paren(A).
473
474format_where(L) when is_integer(L) ->
475    io_lib:format("(line ~p)", [L]);
476format_where({L,C}) when is_integer(L), is_integer(C) ->
477    io_lib:format("(line ~p, column ~p)", [L, C]).
478
479%% Local functions that are somehow automatically generated.
480
481pseudolocals() ->
482    [{module_info,0}, {module_info,1}, {record_info,2}].
483
484%%
485%% Used by erl_eval.erl to check commands.
486%%
487exprs(Exprs, BindingsList) ->
488    exprs_opt(Exprs, BindingsList, []).
489
490exprs_opt(Exprs, BindingsList, Opts) ->
491    {St0,Vs} = foldl(fun({{record,_SequenceNumber,_Name},Attr0}, {St1,Vs1}) ->
492                             Attr = set_file(Attr0, "none"),
493			     {attribute_state(Attr, St1),Vs1};
494                        ({V,_}, {St1,Vs1}) ->
495			     {St1,[{V,{bound,unused,[]}} | Vs1]}
496		     end, {start("nofile",Opts),[]}, BindingsList),
497    Vt = orddict:from_list(Vs),
498    {_Evt,St} = exprs(set_file(Exprs, "nofile"), Vt, St0),
499    return_status(St).
500
501used_vars(Exprs, BindingsList) ->
502    Vs = foldl(fun({{record,_SequenceNumber,_Name},_Attr}, Vs0) -> Vs0;
503		  ({V,_Val}, Vs0) -> [{V,{bound,unused,[]}} | Vs0]
504	       end, [], BindingsList),
505    Vt = orddict:from_list(Vs),
506    {Evt,_St} = exprs(set_file(Exprs, "nofile"), Vt, start()),
507    {ok, foldl(fun({V,{_,used,_}}, L) -> [V | L];
508                  (_, L) -> L
509	       end, [], Evt)}.
510
511%% module([Form]) ->
512%% module([Form], FileName) ->
513%% module([Form], FileName, [CompileOption]) ->
514%%      {ok,[Warning]} | {error,[Error],[Warning]}
515%%  Start processing a module. Define predefined functions and exports and
516%%  apply_lambda/2 has been called to shut lint up. N.B. these lists are
517%%  really all ordsets!
518
519-spec(module(AbsForms) -> {ok, Warnings} | {error, Errors, Warnings} when
520      AbsForms :: [erl_parse:abstract_form() | erl_parse:form_info()],
521      Warnings :: [{file:filename(),[ErrorInfo]}],
522      Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
523      ErrorInfo :: error_info()).
524
525module(Forms) ->
526    Opts = compiler_options(Forms),
527    St = forms(Forms, start("nofile", Opts)),
528    return_status(St).
529
530-spec(module(AbsForms, FileName) ->
531             {ok, Warnings} | {error, Errors, Warnings} when
532      AbsForms :: [erl_parse:abstract_form() | erl_parse:form_info()],
533      FileName :: atom() | string(),
534      Warnings :: [{file:filename(),[ErrorInfo]}],
535      Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
536      ErrorInfo :: error_info()).
537
538module(Forms, FileName) ->
539    Opts = compiler_options(Forms),
540    St = forms(Forms, start(FileName, Opts)),
541    return_status(St).
542
543-spec(module(AbsForms, FileName, CompileOptions) ->
544             {ok, Warnings} | {error, Errors, Warnings} when
545      AbsForms :: [erl_parse:abstract_form() | erl_parse:form_info()],
546      FileName :: atom() | string(),
547      CompileOptions :: [compile:option()],
548      Warnings :: [{file:filename(),[ErrorInfo]}],
549      Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
550      ErrorInfo :: error_info()).
551
552module(Forms, FileName, Opts0) ->
553    %% We want the options given on the command line to take
554    %% precedence over options in the module.
555    Opts = compiler_options(Forms) ++ Opts0,
556    St = forms(Forms, start(FileName, Opts)),
557    return_status(St).
558
559compiler_options(Forms) ->
560    lists:flatten([C || {attribute,_,compile,C} <- Forms]).
561
562%% start() -> State
563%% start(FileName, [Option]) -> State
564
565start() ->
566    start("nofile", []).
567
568start(File, Opts) ->
569    Enabled0 =
570	[{unused_vars,
571	  bool_option(warn_unused_vars, nowarn_unused_vars,
572		      true, Opts)},
573	 {export_all,
574	  bool_option(warn_export_all, nowarn_export_all,
575		      true, Opts)},
576	 {export_vars,
577	  bool_option(warn_export_vars, nowarn_export_vars,
578		      false, Opts)},
579	 {shadow_vars,
580	  bool_option(warn_shadow_vars, nowarn_shadow_vars,
581		      true, Opts)},
582	 {unused_import,
583	  bool_option(warn_unused_import, nowarn_unused_import,
584		      false, Opts)},
585	 {unused_function,
586	  bool_option(warn_unused_function, nowarn_unused_function,
587		      true, Opts)},
588	 {unused_type,
589	  bool_option(warn_unused_type, nowarn_unused_type,
590		      true, Opts)},
591	 {bif_clash,
592	  bool_option(warn_bif_clash, nowarn_bif_clash,
593		      true, Opts)},
594	 {unused_record,
595	  bool_option(warn_unused_record, nowarn_unused_record,
596		      true, Opts)},
597	 {deprecated_function,
598	  bool_option(warn_deprecated_function, nowarn_deprecated_function,
599		      true, Opts)},
600	 {deprecated_type,
601	  bool_option(warn_deprecated_type, nowarn_deprecated_type,
602		      true, Opts)},
603         {obsolete_guard,
604          bool_option(warn_obsolete_guard, nowarn_obsolete_guard,
605                      true, Opts)},
606	 {untyped_record,
607	  bool_option(warn_untyped_record, nowarn_untyped_record,
608		      false, Opts)},
609	 {missing_spec,
610	  bool_option(warn_missing_spec, nowarn_missing_spec,
611		      false, Opts)},
612	 {missing_spec_all,
613	  bool_option(warn_missing_spec_all, nowarn_missing_spec_all,
614		      false, Opts)},
615         {removed,
616          bool_option(warn_removed, nowarn_removed,
617                      true, Opts)},
618         {nif_inline,
619          bool_option(warn_nif_inline, nowarn_nif_inline,
620                      true, Opts)}
621	],
622    Enabled1 = [Category || {Category,true} <- Enabled0],
623    Enabled = ordsets:from_list(Enabled1),
624    Calls = case ordsets:is_element(unused_function, Enabled) of
625		true ->
626		    maps:from_list([{{module_info,1},pseudolocals()}]);
627		false ->
628		    undefined
629	    end,
630    #lint{state = start,
631          exports = gb_sets:from_list([{module_info,0},{module_info,1}]),
632          compile = Opts,
633          %% Internal pseudo-functions must appear as defined/reached.
634          defined = gb_sets:from_list(pseudolocals()),
635	  called = [{F,0} || F <- pseudolocals()],
636          usage = #usage{calls=Calls},
637          warn_format = value_option(warn_format, 1, warn_format, 1,
638				     nowarn_format, 0, Opts),
639	  enabled_warnings = Enabled,
640          nowarn_bif_clash = nowarn_function(nowarn_bif_clash, Opts),
641          file = File
642         }.
643
644%% is_warn_enabled(Category, St) -> boolean().
645%%  Check whether a warning of category Category is enabled.
646is_warn_enabled(Type, #lint{enabled_warnings=Enabled}) ->
647    ordsets:is_element(Type, Enabled).
648
649%% return_status(State) ->
650%%      {ok,[Warning]} | {error,[Error],[Warning]}
651%%  Pack errors and warnings properly and return ok | error.
652
653return_status(St) ->
654    Ws = pack_warnings(St#lint.warnings),
655    case pack_errors(St#lint.errors) of
656        [] -> {ok,Ws};
657        Es -> {error,Es,Ws}
658    end.
659
660%% pack_errors([{File,ErrD}]) -> [{File,[ErrD]}].
661%%  Sort on (reversed) insertion order.
662
663pack_errors(Es) ->
664    {Es1,_} = mapfoldl(fun ({File,E}, I) -> {{File,{I,E}}, I-1} end, -1, Es),
665    map(fun ({File,EIs}) -> {File, map(fun ({_I,E}) -> E end, EIs)} end,
666        pack_warnings(Es1)).
667
668%% pack_warnings([{File,ErrD}]) -> [{File,[ErrD]}]
669%%  Sort on line number.
670
671pack_warnings(Ws) ->
672    [{File,lists:sort([W || {F,W} <- Ws, F =:= File])} ||
673        File <- lists:usort([F || {F,_} <- Ws])].
674
675%% add_error(ErrorDescriptor, State) -> State'
676%% add_error(Line, Error, State) -> State'
677%% add_warning(ErrorDescriptor, State) -> State'
678%% add_warning(Line, Error, State) -> State'
679
680add_error(E, St) -> add_lint_error(E, St#lint.file, St).
681
682add_error(Anno, E0, #lint{gexpr_context=Context}=St) ->
683    E = case {E0,Context} of
684            {illegal_guard_expr,bin_seg_size} ->
685                illegal_bitsize;
686            {{illegal_guard_local_call,FA},bin_seg_size} ->
687                {illegal_bitsize_local_call,FA};
688            {_,_} -> E0
689        end,
690    {File,Location} = loc(Anno, St),
691    add_lint_error({Location,erl_lint,E}, File, St).
692
693add_lint_error(E, File, St) ->
694    St#lint{errors=[{File,E}|St#lint.errors]}.
695
696add_warning(W, St) -> add_lint_warning(W, St#lint.file, St).
697
698add_warning(FileLine, W, St) ->
699    {File,Location} = loc(FileLine, St),
700    add_lint_warning({Location,erl_lint,W}, File, St).
701
702add_lint_warning(W, File, St) ->
703    St#lint{warnings=[{File,W}|St#lint.warnings]}.
704
705loc(Anno, St) ->
706    Location = erl_anno:location(Anno),
707    case erl_anno:file(Anno) of
708        undefined -> {St#lint.file,Location};
709        File -> {File,Location}
710    end.
711
712%% forms([Form], State) -> State'
713
714forms(Forms0, St0) ->
715    Forms = eval_file_attribute(Forms0, St0),
716    %% Annotations from now on include the 'file' item.
717    Locals = local_functions(Forms),
718    AutoImportSuppressed = auto_import_suppressed(St0#lint.compile),
719    StDeprecated = disallowed_compile_flags(Forms,St0),
720    St1 = includes_qlc_hrl(Forms, StDeprecated#lint{locals = Locals,
721						    no_auto = AutoImportSuppressed}),
722    St2 = bif_clashes(Forms, St1),
723    St3 = not_deprecated(Forms, St2),
724    St4 = not_removed(Forms, St3),
725    St5 = foldl(fun form/2, pre_scan(Forms, St4), Forms),
726    post_traversal_check(Forms, St5).
727
728pre_scan([{attribute,L,compile,C} | Fs], St) ->
729    case is_warn_enabled(export_all, St) andalso
730	member(export_all, lists:flatten([C])) of
731 	true ->
732	    pre_scan(Fs, add_warning(L, export_all, St));
733 	false ->
734	    pre_scan(Fs, St)
735    end;
736pre_scan([_ | Fs], St) ->
737    pre_scan(Fs, St);
738pre_scan([], St) ->
739    St.
740
741includes_qlc_hrl(Forms, St) ->
742    %% QLC calls erl_lint several times, sometimes with the compile
743    %% attribute removed. The file attribute, however, is left as is.
744    QH = [File || {attribute,_,file,{File,_line}} <- Forms,
745                  filename:basename(File) =:= "qlc.hrl"],
746    St#lint{xqlc = QH =/= []}.
747
748eval_file_attribute(Forms, St) ->
749    eval_file_attr(Forms, St#lint.file).
750
751eval_file_attr([{attribute,_L,file,{File,_Line}}=Form | Forms], _File) ->
752    [Form | eval_file_attr(Forms, File)];
753eval_file_attr([Form0 | Forms], File) ->
754    Form = set_form_file(Form0, File),
755    [Form | eval_file_attr(Forms, File)];
756eval_file_attr([], _File) ->
757    [].
758
759%% Sets the file only on the form. This is used on post-traversal.
760%% For the remaining of the AST we rely on #lint.file.
761
762set_form_file({attribute,L,K,V}, File) ->
763    {attribute,erl_anno:set_file(File, L),K,V};
764set_form_file({function,L,N,A,C}, File) ->
765    {function,erl_anno:set_file(File, L),N,A,C};
766set_form_file(Form, _File) ->
767    Form.
768
769set_file(Ts, File) when is_list(Ts) ->
770    [anno_set_file(T, File) || T <- Ts];
771set_file(T, File) ->
772    anno_set_file(T, File).
773
774anno_set_file(T, File) ->
775    F = fun(Anno) -> erl_anno:set_file(File, Anno) end,
776    erl_parse:map_anno(F, T).
777
778%% form(Form, State) -> State'
779%%  Check a form returning the updated State. Handle generic cases here.
780
781form({error,E}, St)   -> add_error(E, St);
782form({warning,W}, St) -> add_warning(W, St);
783form({attribute,_L,file,{File,_Line}}, St) ->
784    St#lint{file = File};
785form({attribute,_L,compile,_}, St) ->
786    St;
787form(Form, #lint{state=State}=St) ->
788    case State of
789	start -> start_state(Form, St);
790	attribute -> attribute_state(Form, St);
791	function -> function_state(Form, St)
792    end.
793
794%% start_state(Form, State) -> State'
795
796start_state({attribute,Line,module,{_,_}}=Form, St0) ->
797    St1 = add_error(Line, pmod_unsupported, St0),
798    attribute_state(Form, St1#lint{state=attribute});
799start_state({attribute,Line,module,M}, St0) ->
800    St1 = St0#lint{module=M},
801    St2 = St1#lint{state=attribute},
802    check_module_name(M, Line, St2);
803start_state(Form, St) ->
804    Anno = case Form of
805               {eof, L} -> erl_anno:new(L);
806               %% {warning, Warning} and {error, Error} not possible here.
807               _ -> element(2, Form)
808           end,
809    St1 = add_error(Anno, undefined_module, St),
810    attribute_state(Form, St1#lint{state=attribute}).
811
812%% attribute_state(Form, State) ->
813%%      State'
814
815attribute_state({attribute,_L,module,_M}, #lint{module=''}=St) ->
816    St;
817attribute_state({attribute,L,module,_M}, St) ->
818    add_error(L, redefine_module, St);
819attribute_state({attribute,L,export,Es}, St) ->
820    export(L, Es, St);
821attribute_state({attribute,L,export_type,Es}, St) ->
822    export_type(L, Es, St);
823attribute_state({attribute,L,import,Is}, St) ->
824    import(L, Is, St);
825attribute_state({attribute,L,record,{Name,Fields}}, St) ->
826    record_def(L, Name, Fields, St);
827attribute_state({attribute,La,behaviour,Behaviour}, St) ->
828    St#lint{behaviour=St#lint.behaviour ++ [{La,Behaviour}]};
829attribute_state({attribute,La,behavior,Behaviour}, St) ->
830    St#lint{behaviour=St#lint.behaviour ++ [{La,Behaviour}]};
831attribute_state({attribute,L,type,{TypeName,TypeDef,Args}}, St) ->
832    type_def(type, L, TypeName, TypeDef, Args, St);
833attribute_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) ->
834    type_def(opaque, L, TypeName, TypeDef, Args, St);
835attribute_state({attribute,L,spec,{Fun,Types}}, St) ->
836    spec_decl(L, Fun, Types, St);
837attribute_state({attribute,L,callback,{Fun,Types}}, St) ->
838    callback_decl(L, Fun, Types, St);
839attribute_state({attribute,L,optional_callbacks,Es}, St) ->
840    optional_callbacks(L, Es, St);
841attribute_state({attribute,L,on_load,Val}, St) ->
842    on_load(L, Val, St);
843attribute_state({attribute,_L,_Other,_Val}, St) -> % Ignore others
844    St;
845attribute_state(Form, St) ->
846    function_state(Form, St#lint{state=function}).
847
848%% function_state(Form, State) ->
849%%      State'
850%%  Allow for record, type and opaque type definitions and spec
851%%  declarations to be intersperced within function definitions.
852%%  Dialyzer attributes are also allowed everywhere.
853
854function_state({attribute,L,record,{Name,Fields}}, St) ->
855    record_def(L, Name, Fields, St);
856function_state({attribute,L,type,{TypeName,TypeDef,Args}}, St) ->
857    type_def(type, L, TypeName, TypeDef, Args, St);
858function_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) ->
859    type_def(opaque, L, TypeName, TypeDef, Args, St);
860function_state({attribute,L,spec,{Fun,Types}}, St) ->
861    spec_decl(L, Fun, Types, St);
862function_state({attribute,_L,dialyzer,_Val}, St) ->
863    St;
864function_state({attribute,La,Attr,_Val}, St) ->
865    add_error(La, {attribute,Attr}, St);
866function_state({function,L,N,A,Cs}, St) ->
867    function(L, N, A, Cs, St);
868function_state({eof,L}, St) -> eof(L, St).
869
870%% eof(LastLine, State) ->
871%%      State'
872
873eof(_Line, St0) ->
874    St0.
875
876%% bif_clashes(Forms, State0) -> State.
877
878bif_clashes(Forms, #lint{nowarn_bif_clash=Nowarn} = St) ->
879    Clashes0 = [{Name,Arity} || {function,_L,Name,Arity,_Cs} <- Forms,
880                                erl_internal:bif(Name, Arity)],
881    Clashes = ordsets:subtract(ordsets:from_list(Clashes0), Nowarn),
882    St#lint{clashes=Clashes}.
883
884%% not_deprecated(Forms, State0) -> State
885
886not_deprecated(Forms, #lint{compile=Opts}=St0) ->
887    %% There are no line numbers in St0#lint.compile.
888    MFAsL = [{MFA,L} ||
889                {attribute, L, compile, Args} <- Forms,
890                {nowarn_deprecated_function, MFAs0} <- lists:flatten([Args]),
891                MFA <- lists:flatten([MFAs0])],
892    Nowarn = [MFA ||
893                 {nowarn_deprecated_function, MFAs0} <- Opts,
894                 MFA <- lists:flatten([MFAs0])],
895    ML = [{M,L} || {{M,_F,_A},L} <- MFAsL, is_atom(M)],
896    St1 = foldl(fun ({M,L}, St2) ->
897                        check_module_name(M, L, St2)
898                end, St0, ML),
899    St1#lint{not_deprecated = ordsets:from_list(Nowarn)}.
900
901%% not_removed(Forms, State0) -> State
902
903not_removed(Forms, #lint{compile=Opts}=St0) ->
904    %% There are no line numbers in St0#lint.compile.
905    MFAsL = [{MFA,L} ||
906                {attribute, L, compile, Args} <- Forms,
907                {nowarn_removed, MFAs0} <- lists:flatten([Args]),
908                MFA <- lists:flatten([MFAs0])],
909    Nowarn = [MFA ||
910                 {nowarn_removed, MFAs0} <- Opts,
911                 MFA <- lists:flatten([MFAs0])],
912    St1 = foldl(fun ({{M, _F, _A}, L}, St2) ->
913                        check_module_name(M, L, St2);
914                    ({M,L}, St2) ->
915                        check_module_name(M, L, St2)
916                end, St0, MFAsL),
917    St1#lint{not_removed = gb_sets:from_list(Nowarn)}.
918
919%% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A
920disallowed_compile_flags(Forms, St0) ->
921    %% There are (still) no line numbers in St0#lint.compile.
922    Errors0 =  [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
923		    {attribute,A,compile,nowarn_bif_clash} <- Forms,
924                   {_,L} <- [loc(A, St0)] ],
925    Errors1 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
926		    {attribute,A,compile,{nowarn_bif_clash, {_,_}}} <- Forms,
927                   {_,L} <- [loc(A, St0)] ],
928    Disabled = (not is_warn_enabled(bif_clash, St0)),
929    Errors = if
930		   Disabled andalso Errors0 =:= [] ->
931		       [{St0#lint.file,{erl_lint,disallowed_nowarn_bif_clash}} | St0#lint.errors];
932                   Disabled ->
933		       Errors0 ++ Errors1 ++ St0#lint.errors;
934		   true ->
935		       Errors1 ++ St0#lint.errors
936	       end,
937    St0#lint{errors=Errors}.
938
939%% post_traversal_check(Forms, State0) -> State.
940%% Do some further checking after the forms have been traversed and
941%% data about calls etc. have been collected.
942
943post_traversal_check(Forms, St0) ->
944    St1 = check_behaviour(St0),
945    St2 = check_deprecated(Forms, St1),
946    St3 = check_imports(Forms, St2),
947    St4 = check_inlines(Forms, St3),
948    St5 = check_undefined_functions(St4),
949    St6 = check_unused_functions(Forms, St5),
950    St7 = check_bif_clashes(Forms, St6),
951    St8 = check_specs_without_function(St7),
952    St9 = check_functions_without_spec(Forms, St8),
953    StA = check_undefined_types(St9),
954    StB = check_unused_types(Forms, StA),
955    StC = check_untyped_records(Forms, StB),
956    StD = check_on_load(StC),
957    StE = check_unused_records(Forms, StD),
958    StF = check_local_opaque_types(StE),
959    StG = check_dialyzer_attribute(Forms, StF),
960    StH = check_callback_information(StG),
961    check_removed(Forms, StH).
962
963%% check_behaviour(State0) -> State
964%% Check that the behaviour attribute is valid.
965
966check_behaviour(St0) ->
967    behaviour_check(St0#lint.behaviour, St0).
968
969%% behaviour_check([{Line,Behaviour}], State) -> State'
970%%  Check behaviours for existence and defined functions.
971
972behaviour_check(Bs, St0) ->
973    {AllBfs0, St1} = all_behaviour_callbacks(Bs, [], St0),
974    St = behaviour_missing_callbacks(AllBfs0, St1),
975    Exports = exports(St0),
976    F = fun(Bfs, OBfs) ->
977                [B || B <- Bfs,
978                      not lists:member(B, OBfs)
979                      orelse gb_sets:is_member(B, Exports)]
980        end,
981    %% After fixing missing callbacks new warnings may be emitted.
982    AllBfs = [{Item,F(Bfs0, OBfs0)} || {Item,Bfs0,OBfs0} <- AllBfs0],
983    behaviour_conflicting(AllBfs, St).
984
985all_behaviour_callbacks([{Line,B}|Bs], Acc, St0) ->
986    {Bfs0,OBfs0,St} = behaviour_callbacks(Line, B, St0),
987    all_behaviour_callbacks(Bs, [{{Line,B},Bfs0,OBfs0}|Acc], St);
988all_behaviour_callbacks([], Acc, St) -> {reverse(Acc),St}.
989
990behaviour_callbacks(Line, B, St0) ->
991    try B:behaviour_info(callbacks) of
992        undefined ->
993            St1 = add_warning(Line, {undefined_behaviour_callbacks, B}, St0),
994            {[], [], St1};
995        Funcs ->
996            case is_fa_list(Funcs) of
997                true ->
998                    try B:behaviour_info(optional_callbacks) of
999                        undefined ->
1000                            {Funcs, [], St0};
1001                        OptFuncs ->
1002                            %% OptFuncs should always be OK thanks to
1003                            %% sys_pre_expand.
1004                            case is_fa_list(OptFuncs) of
1005                                true ->
1006                                    {Funcs, OptFuncs, St0};
1007                                false ->
1008                                    W = {ill_defined_optional_callbacks, B},
1009                                    St1 = add_warning(Line, W, St0),
1010                                    {Funcs, [], St1}
1011                            end
1012                    catch
1013                        _:_ ->
1014                            {Funcs, [], St0}
1015                    end;
1016                false ->
1017                    St1 = add_warning(Line,
1018                                      {ill_defined_behaviour_callbacks, B},
1019                                      St0),
1020                    {[], [], St1}
1021            end
1022    catch
1023        _:_ ->
1024            St1 = add_warning(Line, {undefined_behaviour, B}, St0),
1025            St2 = check_module_name(B, Line, St1),
1026            {[], [], St2}
1027    end.
1028
1029behaviour_missing_callbacks([{{Line,B},Bfs0,OBfs}|T], St0) ->
1030    Bfs = ordsets:subtract(ordsets:from_list(Bfs0), ordsets:from_list(OBfs)),
1031    Exports = gb_sets:to_list(exports(St0)),
1032    Missing = ordsets:subtract(Bfs, Exports),
1033    St = foldl(fun (F, S0) ->
1034                       case is_fa(F) of
1035                           true ->
1036                               M = {undefined_behaviour_func,F,B},
1037                               add_warning(Line, M, S0);
1038                           false ->
1039                               S0 % ill_defined_behaviour_callbacks
1040                       end
1041	       end, St0, Missing),
1042    behaviour_missing_callbacks(T, St);
1043behaviour_missing_callbacks([], St) -> St.
1044
1045behaviour_conflicting(AllBfs, St) ->
1046    R0 = sofs:relation(AllBfs, [{item,[callback]}]),
1047    R1 = sofs:family_to_relation(R0),
1048    R2 = sofs:converse(R1),
1049    R3 = sofs:relation_to_family(R2),
1050    R4 = sofs:family_specification(fun(S) -> sofs:no_elements(S) > 1 end, R3),
1051    R = sofs:to_external(R4),
1052    behaviour_add_conflicts(R, St).
1053
1054behaviour_add_conflicts([{Cb,[{FirstLoc,FirstB}|Cs]}|T], St0) ->
1055    FirstL = element(2, loc(FirstLoc, St0)),
1056    St = behaviour_add_conflict(Cs, Cb, FirstL, FirstB, St0),
1057    behaviour_add_conflicts(T, St);
1058behaviour_add_conflicts([], St) -> St.
1059
1060behaviour_add_conflict([{Line,B}|Cs], Cb, FirstL, FirstB, St0) ->
1061    St = add_warning(Line, {conflicting_behaviours,Cb,B,FirstL,FirstB}, St0),
1062    behaviour_add_conflict(Cs, Cb, FirstL, FirstB, St);
1063behaviour_add_conflict([], _, _, _, St) -> St.
1064
1065%% check_deprecated(Forms, State0) -> State
1066
1067check_deprecated(Forms, St0) ->
1068    %% Get the correct list of exported functions.
1069    Exports = case member(export_all, St0#lint.compile) of
1070		  true -> St0#lint.defined;
1071		  false -> St0#lint.exports
1072	      end,
1073    X = ignore_predefined_funcs(gb_sets:to_list(Exports)),
1074    #lint{module = Mod} = St0,
1075    Bad = [{E,L} || {attribute, L, deprecated, Depr} <- Forms,
1076                    D <- lists:flatten([Depr]),
1077                    E <- depr_cat(D, X, Mod)],
1078    foldl(fun ({E,L}, St1) ->
1079                  add_error(L, E, St1)
1080          end, St0, Bad).
1081
1082depr_cat({F, A, Flg}=D, X, Mod) ->
1083    case deprecated_flag(Flg) of
1084        false -> [{invalid_deprecated,D}];
1085        true -> depr_fa(F, A, X, Mod)
1086    end;
1087depr_cat({F, A}, X, Mod) ->
1088    depr_fa(F, A, X, Mod);
1089depr_cat(module, _X, _Mod) ->
1090    [];
1091depr_cat(D, _X, _Mod) ->
1092    [{invalid_deprecated,D}].
1093
1094depr_fa('_', '_', _X, _Mod) ->
1095    [];
1096depr_fa(F, '_', X, _Mod) when is_atom(F) ->
1097    %% Don't use this syntax for built-in functions.
1098    case lists:filter(fun({F1,_}) -> F1 =:= F end, X) of
1099        [] -> [{bad_deprecated,{F,'_'}}];
1100        _ -> []
1101    end;
1102depr_fa(F, A, X, Mod) when is_atom(F), is_integer(A), A >= 0 ->
1103    case lists:member({F,A}, X) of
1104        true -> [];
1105        false ->
1106            case erlang:is_builtin(Mod, F, A) of
1107                true -> [];
1108                false -> [{bad_deprecated,{F,A}}]
1109            end
1110    end;
1111depr_fa(F, A, _X, _Mod) ->
1112    [{invalid_deprecated,{F,A}}].
1113
1114deprecated_flag(next_version) -> true;
1115deprecated_flag(next_major_release) -> true;
1116deprecated_flag(eventually) -> true;
1117deprecated_flag(String) -> deprecated_desc(String).
1118
1119deprecated_desc([Char | Str]) when is_integer(Char) -> deprecated_desc(Str);
1120deprecated_desc([]) -> true;
1121deprecated_desc(_) -> false.
1122
1123%% check_removed(Forms, State0) -> State
1124
1125check_removed(Forms, St0) ->
1126    %% Get the correct list of exported functions.
1127    Exports = case member(export_all, St0#lint.compile) of
1128                  true -> St0#lint.defined;
1129                  false -> St0#lint.exports
1130              end,
1131    X = ignore_predefined_funcs(gb_sets:to_list(Exports)),
1132    #lint{module = Mod} = St0,
1133    Bad = [{E,L} || {attribute, L, removed, Removed} <- Forms,
1134                    R <- lists:flatten([Removed]),
1135                    E <- removed_cat(R, X, Mod)],
1136    foldl(fun ({E,L}, St1) ->
1137                  add_error(L, E, St1)
1138          end, St0, Bad).
1139
1140removed_cat({F, A, Desc}=R, X, Mod) ->
1141    case removed_desc(Desc) of
1142        false -> [{invalid_removed,R}];
1143        true -> removed_fa(F, A, X, Mod)
1144    end;
1145removed_cat({F, A}, X, Mod) ->
1146    removed_fa(F, A, X, Mod);
1147removed_cat(module, X, Mod) ->
1148    removed_fa('_', '_', X, Mod);
1149removed_cat(R, _X, _Mod) ->
1150    [{invalid_removed,R}].
1151
1152removed_fa('_', '_', X, _Mod) ->
1153    case X of
1154        [_|_] -> [{bad_removed,{'_','_'}}];
1155        [] -> []
1156    end;
1157removed_fa(F, '_', X, _Mod) when is_atom(F) ->
1158    %% Don't use this syntax for built-in functions.
1159    case lists:filter(fun({F1,_}) -> F1 =:= F end, X) of
1160        [_|_] -> [{bad_removed,{F,'_'}}];
1161        _ -> []
1162    end;
1163removed_fa(F, A, X, Mod) when is_atom(F), is_integer(A), A >= 0 ->
1164    case lists:member({F,A}, X) of
1165        true ->
1166            [{bad_removed,{F,A}}];
1167        false ->
1168            case erlang:is_builtin(Mod, F, A) of
1169                true -> [{bad_removed,{F,A}}];
1170                false -> []
1171            end
1172    end;
1173removed_fa(F, A, _X, _Mod) ->
1174    [{invalid_removed,{F,A}}].
1175
1176removed_desc([Char | Str]) when is_integer(Char) -> removed_desc(Str);
1177removed_desc([]) -> true;
1178removed_desc(_) -> false.
1179
1180%% Ignores functions added by erl_internal:add_predefined_functions/1
1181ignore_predefined_funcs([{behaviour_info,1} | Fs]) ->
1182    ignore_predefined_funcs(Fs);
1183ignore_predefined_funcs([{module_info,0} | Fs]) ->
1184    ignore_predefined_funcs(Fs);
1185ignore_predefined_funcs([{module_info,1} | Fs]) ->
1186    ignore_predefined_funcs(Fs);
1187ignore_predefined_funcs([Other | Fs]) ->
1188    [Other | ignore_predefined_funcs(Fs)];
1189ignore_predefined_funcs([]) ->
1190    [].
1191
1192%% check_imports(Forms, State0) -> State
1193
1194check_imports(Forms, St0) ->
1195    case is_warn_enabled(unused_import, St0) of
1196        false ->
1197            St0;
1198        true ->
1199            Usage = St0#lint.usage,
1200            Unused = ordsets:subtract(St0#lint.imports, Usage#usage.imported),
1201            Imports = [{{FA,Mod},L} ||
1202		 {attribute,L,import,{Mod,Fs}} <- Forms,
1203		 FA <- lists:usort(Fs)],
1204            Bad = [{FM,L} || FM <- Unused, {FM2,L} <- Imports, FM =:= FM2],
1205            func_line_warning(unused_import, Bad, St0)
1206    end.
1207
1208%% check_inlines(Forms, State0) -> State
1209
1210check_inlines(Forms, St0) ->
1211    check_option_functions(Forms, inline, bad_inline, St0).
1212
1213%% check_unused_functions(Forms, State0) -> State
1214
1215check_unused_functions(Forms, St0) ->
1216    St1 = check_option_functions(Forms, nowarn_unused_function,
1217                                 bad_nowarn_unused_function, St0),
1218    Opts = St1#lint.compile,
1219    case member(export_all, Opts) orelse
1220	not is_warn_enabled(unused_function, St1) of
1221        true ->
1222            St1;
1223        false ->
1224            Nowarn = nowarn_function(nowarn_unused_function, Opts),
1225            Usage = St1#lint.usage,
1226            Used = reached_functions(initially_reached(St1),
1227				     Usage#usage.calls),
1228            UsedOrNowarn = ordsets:union(Used, Nowarn),
1229            Unused = ordsets:subtract(gb_sets:to_list(St1#lint.defined),
1230				      UsedOrNowarn),
1231            Functions = [{{N,A},L} || {function,L,N,A,_} <- Forms],
1232            Bad = [{FA,L} || FA <- Unused, {FA2,L} <- Functions, FA =:= FA2],
1233            func_line_warning(unused_function, Bad, St1)
1234    end.
1235
1236initially_reached(#lint{exports=Exp,on_load=OnLoad}) ->
1237    OnLoad ++ gb_sets:to_list(Exp).
1238
1239%% reached_functions(RootSet, CallRef) -> [ReachedFunc].
1240%% reached_functions(RootSet, CallRef, [ReachedFunc]) -> [ReachedFunc].
1241
1242reached_functions(Root, Ref) ->
1243    reached_functions(Root, [], Ref, gb_sets:empty()).
1244
1245reached_functions([R|Rs], More0, Ref, Reached0) ->
1246    case gb_sets:is_element(R, Reached0) of
1247        true -> reached_functions(Rs, More0, Ref, Reached0);
1248        false ->
1249            Reached = gb_sets:add_element(R, Reached0), %It IS reached
1250            case maps:find(R, Ref) of
1251                {ok,More} -> reached_functions(Rs, [More|More0], Ref, Reached);
1252                error -> reached_functions(Rs, More0, Ref, Reached)
1253            end
1254    end;
1255reached_functions([], [_|_]=More, Ref, Reached) ->
1256    reached_functions(lists:append(More), [], Ref, Reached);
1257reached_functions([], [], _Ref, Reached) -> gb_sets:to_list(Reached).
1258
1259%% check_undefined_functions(State0) -> State
1260
1261check_undefined_functions(#lint{called=Called0,defined=Def0}=St0) ->
1262    Called = sofs:relation(Called0, [{func,location}]),
1263    Def = sofs:from_external(gb_sets:to_list(Def0), [func]),
1264    Undef = sofs:to_external(sofs:drestriction(Called, Def)),
1265    foldl(fun ({NA,L}, St) ->
1266		  add_error(L, {undefined_function,NA}, St)
1267	  end, St0, Undef).
1268
1269%% check_undefined_types(State0) -> State
1270
1271check_undefined_types(#lint{usage=Usage,types=Def}=St0) ->
1272    Used = Usage#usage.used_types,
1273    UTAs = maps:keys(Used),
1274    Undef = [{TA,map_get(TA, Used)} ||
1275		TA <- UTAs,
1276		not is_map_key(TA, Def),
1277		not is_default_type(TA)],
1278    foldl(fun ({TA,L}, St) ->
1279		  add_error(L, {undefined_type,TA}, St)
1280	  end, St0, Undef).
1281
1282%% check_bif_clashes(Forms, State0) -> State
1283
1284check_bif_clashes(Forms, St0) ->
1285    %% St0#lint.defined is now complete.
1286    check_option_functions(Forms, nowarn_bif_clash,
1287                           bad_nowarn_bif_clash, St0).
1288
1289check_option_functions(Forms, Tag0, Type, St0) ->
1290    %% There are no line numbers in St0#lint.compile.
1291    FAsL = [{FA,L} || {attribute, L, compile, Args} <- Forms,
1292                      {Tag, FAs0} <- lists:flatten([Args]),
1293                      Tag0 =:= Tag,
1294                      FA <- lists:flatten([FAs0])],
1295    DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()) ++
1296	[{F,A} || {{F,A},_} <- orddict:to_list(St0#lint.imports)],
1297    Bad = [{FA,L} || {FA,L} <- FAsL, not member(FA, DefFunctions)],
1298    func_line_error(Type, Bad, St0).
1299
1300nowarn_function(Tag, Opts) ->
1301    ordsets:from_list([FA || {Tag1,FAs} <- Opts,
1302                             Tag1 =:= Tag,
1303                             FA <- lists:flatten([FAs])]).
1304
1305func_line_warning(Type, Fs, St) ->
1306    foldl(fun ({F,Line}, St0) -> add_warning(Line, {Type,F}, St0) end, St, Fs).
1307
1308func_line_error(Type, Fs, St) ->
1309    foldl(fun ({F,Line}, St0) -> add_error(Line, {Type,F}, St0) end, St, Fs).
1310
1311check_untyped_records(Forms, St0) ->
1312    case is_warn_enabled(untyped_record, St0) of
1313	true ->
1314	    %% Use the names of all records *defined* in the module (not used)
1315	    RecNames = maps:keys(St0#lint.records),
1316	    %% these are the records with field(s) containing type info
1317	    TRecNames = [Name ||
1318			    {attribute,_,record,{Name,Fields}} <- Forms,
1319			    lists:all(fun ({typed_record_field,_,_}) -> true;
1320					  (_) -> false
1321				      end, Fields)],
1322	    foldl(fun (N, St) ->
1323			  {L, Fields} = map_get(N, St0#lint.records),
1324			  case Fields of
1325			      [] -> St; % exclude records with no fields
1326			      [_|_] -> add_warning(L, {untyped_record, N}, St)
1327			  end
1328		  end, St0, ordsets:subtract(ordsets:from_list(RecNames),
1329                                             ordsets:from_list(TRecNames)));
1330	false ->
1331	    St0
1332    end.
1333
1334check_unused_records(Forms, St0) ->
1335    AttrFiles = [File || {attribute,_L,file,{File,_Line}} <- Forms],
1336    case {is_warn_enabled(unused_record, St0),AttrFiles} of
1337        {true,[FirstFile|_]} ->
1338            %% The check is a bit imprecise in that uses from unused
1339            %% functions count.
1340            Usage = St0#lint.usage,
1341            UsedRecords = Usage#usage.used_records,
1342            URecs = gb_sets:fold(fun (Used, Recs) ->
1343                                         maps:remove(Used, Recs)
1344                                 end, St0#lint.records, UsedRecords),
1345            Unused = [{Name,FileLine} ||
1346                         {Name,{FileLine,_Fields}} <- maps:to_list(URecs),
1347                         element(1, loc(FileLine, St0)) =:= FirstFile],
1348            foldl(fun ({N,L}, St) ->
1349                          add_warning(L, {unused_record, N}, St)
1350                  end, St0, Unused);
1351        _ ->
1352            St0
1353    end.
1354
1355check_callback_information(#lint{callbacks = Callbacks,
1356                                 optional_callbacks = OptionalCbs,
1357				 defined = Defined} = St0) ->
1358    OptFun = fun(MFA, Line, St) ->
1359                     case is_map_key(MFA, Callbacks) of
1360                         true ->
1361                             St;
1362                         false ->
1363                             add_error(Line, {undefined_callback, MFA}, St)
1364                     end
1365             end,
1366    St1 = maps:fold(OptFun, St0, OptionalCbs),
1367    case gb_sets:is_member({behaviour_info, 1}, Defined) of
1368	false -> St1;
1369	true ->
1370	    case map_size(Callbacks) of
1371		0 -> St1;
1372		_ ->
1373                    FoldFun =
1374			fun(Fa, Line, St) ->
1375				add_error(Line, {behaviour_info, Fa}, St)
1376			end,
1377                    maps:fold(FoldFun, St1, Callbacks)
1378	    end
1379    end.
1380
1381%% For storing the import list we use the orddict module.
1382%% We know an empty set is [].
1383
1384-spec export(line(), [fa()], lint_state()) -> lint_state().
1385%%  Mark functions as exported, also as called from the export line.
1386
1387export(Line, Es, #lint{exports = Es0, called = Called} = St0) ->
1388    {Es1,C1,St1} =
1389        foldl(fun (NA, {E,C,St2}) ->
1390                      St = case gb_sets:is_element(NA, E) of
1391                               true ->
1392                                   Warn = {duplicated_export,NA},
1393                                   add_warning(Line, Warn, St2);
1394                               false ->
1395                                   St2
1396                           end,
1397                      {gb_sets:add_element(NA, E), [{NA,Line}|C], St}
1398              end,
1399              {Es0,Called,St0}, Es),
1400    St1#lint{exports = Es1, called = C1}.
1401
1402-spec export_type(line(), [ta()], lint_state()) -> lint_state().
1403%%  Mark types as exported; also mark them as used from the export line.
1404
1405export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) ->
1406    UTs0 = Usage#usage.used_types,
1407    try foldl(fun ({T,A}=TA, {E,U,St2}) when is_atom(T), is_integer(A) ->
1408		      St = case gb_sets:is_element(TA, E) of
1409			       true ->
1410				   Warn = {duplicated_export_type,TA},
1411				   add_warning(Line, Warn, St2);
1412			       false ->
1413				   St2
1414			   end,
1415		      {gb_sets:add_element(TA, E), maps:put(TA, Line, U), St}
1416	      end,
1417	      {ETs0,UTs0,St0}, ETs) of
1418	{ETs1,UTs1,St1} ->
1419	    St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1}
1420    catch
1421	error:_ ->
1422	    add_error(Line, {bad_export_type, ETs}, St0)
1423    end.
1424
1425-spec exports(lint_state()) -> gb_sets:set(fa()).
1426
1427exports(#lint{compile = Opts, defined = Defs, exports = Es}) ->
1428    case lists:member(export_all, Opts) of
1429        true -> Defs;
1430        false -> Es
1431    end.
1432
1433-type import() :: {module(), [fa()]} | module().
1434-spec import(line(), import(), lint_state()) -> lint_state().
1435
1436import(Line, {Mod,Fs}, St00) ->
1437    St = check_module_name(Mod, Line, St00),
1438    Mfs = ordsets:from_list(Fs),
1439    case check_imports(Line, Mfs, St#lint.imports) of
1440	[] ->
1441	    St#lint{imports=add_imports(Mod, Mfs,
1442					St#lint.imports)};
1443	Efs ->
1444	    {Err, St1} =
1445		foldl(fun ({bif,{F,A},_}, {Err,St0}) ->
1446			      %% BifClash - import directive
1447			      Warn = is_warn_enabled(bif_clash, St0) andalso
1448				  (not bif_clash_specifically_disabled(St0,{F,A})),
1449			      AutoImpSup = is_autoimport_suppressed(St0#lint.no_auto,{F,A}),
1450			      OldBif = erl_internal:old_bif(F,A),
1451			      {Err,if
1452				       Warn and (not AutoImpSup) and OldBif ->
1453					   add_error
1454					     (Line,
1455					      {redefine_old_bif_import, {F,A}},
1456					      St0);
1457				       Warn and (not AutoImpSup) ->
1458					   add_warning
1459					     (Line,
1460					      {redefine_bif_import, {F,A}},
1461					      St0);
1462				       true ->
1463					   St0
1464				   end};
1465			  (Ef, {_Err,St0}) ->
1466			      {true,add_error(Line,
1467					      {redefine_import,Ef},
1468					      St0)}
1469		      end,
1470		      {false,St}, Efs),
1471	    if
1472		not Err ->
1473		    St1#lint{imports=add_imports(Mod, Mfs,
1474						 St#lint.imports)};
1475		true ->
1476		    St1
1477	    end
1478    end.
1479
1480check_imports(_Line, Fs, Is) ->
1481    foldl(fun (F, Efs) ->
1482              case orddict:find(F, Is) of
1483                  {ok,Mod} -> [{F,Mod}|Efs];
1484                  error ->
1485                      {N,A} = F,
1486                      case erl_internal:bif(N, A) of
1487                          true ->
1488                              [{bif,F,erlang}|Efs];
1489                          false ->
1490                              Efs
1491                      end
1492              end end, [], Fs).
1493
1494add_imports(Mod, Fs, Is) ->
1495    foldl(fun (F, Is0) -> orddict:store(F, Mod, Is0) end, Is, Fs).
1496
1497-spec imported(atom(), arity(), lint_state()) -> {'yes',module()} | 'no'.
1498
1499imported(F, A, St) ->
1500    case orddict:find({F,A}, St#lint.imports) of
1501        {ok,Mod} -> {yes,Mod};
1502        error -> no
1503    end.
1504
1505-spec on_load(erl_anno:anno(), fa(), lint_state()) -> lint_state().
1506%%  Check an on_load directive and remember it.
1507
1508on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0)
1509  when is_atom(Name), is_integer(Arity) ->
1510    %% Always add the function name (even if there is a problem),
1511    %% to avoid irrelevant warnings for unused functions.
1512    St = St0#lint{on_load=[Fa|OnLoad0],on_load_line=Line},
1513    case St of
1514	#lint{on_load=[{_,0}]} ->
1515	    %% This is the first on_load attribute seen in the module
1516	    %% and it has the correct arity.
1517	    St;
1518	#lint{on_load=[{_,_}]} ->
1519	    %% Wrong arity.
1520	    add_error(Line, {bad_on_load_arity,Fa}, St);
1521	#lint{on_load=[_,_|_]} ->
1522	    %% Multiple on_load attributes.
1523	    add_error(Line, multiple_on_loads, St)
1524    end;
1525on_load(Line, Val, St) ->
1526    %% Bad syntax.
1527    add_error(Line, {bad_on_load,Val}, St).
1528
1529check_on_load(#lint{defined=Defined,on_load=[{_,0}=Fa],
1530		    on_load_line=Line}=St) ->
1531    case gb_sets:is_member(Fa, Defined) of
1532	true -> St;
1533	false -> add_error(Line, {undefined_on_load,Fa}, St)
1534    end;
1535check_on_load(St) -> St.
1536
1537-spec call_function(line(), atom(), arity(), lint_state()) -> lint_state().
1538%%  Add to both called and calls.
1539
1540call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func,file=File}=St) ->
1541    #usage{calls = Cs} = Usage0,
1542    NA = {F,A},
1543    Usage = case Cs of
1544		undefined -> Usage0;
1545		_ -> Usage0#usage{calls=maps_prepend(Func, NA, Cs)}
1546	    end,
1547    Anno = erl_anno:set_file(File, Line),
1548    St#lint{called=[{NA,Anno}|Cd], usage=Usage}.
1549
1550%% function(Line, Name, Arity, Clauses, State) -> State.
1551
1552function(Line, Name, Arity, Cs, St0) ->
1553    St1 = St0#lint{func={Name,Arity}},
1554    St2 = define_function(Line, Name, Arity, St1),
1555    clauses(Cs, St2).
1556
1557-spec define_function(line(), atom(), arity(), lint_state()) -> lint_state().
1558
1559define_function(Line, Name, Arity, St0) ->
1560    St1 = keyword_warning(Line, Name, St0),
1561    NA = {Name,Arity},
1562    case gb_sets:is_member(NA, St1#lint.defined) of
1563        true ->
1564            add_error(Line, {redefine_function,NA}, St1);
1565        false ->
1566	    St2 = function_check_max_args(Line, Arity, St1),
1567            St3 = St2#lint{defined=gb_sets:add_element(NA, St2#lint.defined)},
1568            case imported(Name, Arity, St3) of
1569                {yes,_M} -> add_error(Line, {define_import,NA}, St3);
1570                no -> St3
1571            end
1572    end.
1573
1574function_check_max_args(Line, Arity, St) when Arity > ?MAX_ARGUMENTS ->
1575    add_error(Line, {too_many_arguments,Arity}, St);
1576function_check_max_args(_, _, St) -> St.
1577
1578%% clauses([Clause], State) -> {VarTable, State}.
1579
1580clauses(Cs, St) ->
1581    foldl(fun (C, St0) ->
1582                  {_,St1} = clause(C, St0),
1583                  St1
1584          end, St, Cs).
1585
1586clause({clause,_Line,H,G,B}, St0) ->
1587    Vt0 = [],
1588    {Hvt,Binvt,St1} = head(H, Vt0, St0),
1589    %% Cannot ignore BinVt since "binsize variables" may have been used.
1590    Vt1 = vtupdate(Hvt, vtupdate(Binvt, Vt0)),
1591    {Gvt,St2} = guard(G, Vt1, St1),
1592    Vt2 = vtupdate(Gvt, Vt1),
1593    {Bvt,St3} = exprs(B, Vt2, St2),
1594    Upd = vtupdate(Bvt, Vt2),
1595    check_unused_vars(Upd, Vt0, St3).
1596
1597%% head([HeadPattern], VarTable, State) ->
1598%%      {VarTable,BinVarTable,State}
1599%%  Check a patterns in head returning "all" variables. Not updating the
1600%%  known variable list will result in multiple error messages/warnings.
1601
1602head(Ps, Vt, St0) ->
1603    head(Ps, Vt, Vt, St0).    % Old = Vt
1604
1605head([P|Ps], Vt, Old, St0) ->
1606    {Pvt,Bvt1,St1} = pattern(P, Vt, Old, [], St0),
1607    {Psvt,Bvt2,St2} = head(Ps, Vt, Old, St1),
1608    {vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt1,Bvt2),St2};
1609head([], _Vt, _Env, St) -> {[],[],St}.
1610
1611%% pattern(Pattern, VarTable, Old, BinVarTable, State) ->
1612%%                  {UpdVarTable,BinVarTable,State}.
1613%%  Check pattern return variables. Old is the set of variables used for
1614%%  deciding whether an occurrence is a binding occurrence or a use, and
1615%%  VarTable is the set of variables used for arguments to binary
1616%%  patterns. UpdVarTable is updated when same variable in VarTable is
1617%%  used in the size part of a bit segment. All other information about
1618%%  used variables are recorded in BinVarTable. The caller can then decide
1619%%  what to do with it depending on whether variables in the pattern shadow
1620%%  variabler or not. This separation is one way of dealing with these:
1621%%  A = 4, fun(<<A:A>>) -> % A #2 unused
1622%%  A = 4, fun(<<A:8,16:A>>) -> % A #1 unused
1623
1624pattern(P, Vt, St) ->
1625    pattern(P, Vt, Vt, [], St).    % Old = Vt
1626
1627pattern({var,_Line,'_'}, _Vt, _Old, _Bvt, St) ->
1628    {[],[],St}; %Ignore anonymous variable
1629pattern({var,Line,V}, _Vt, Old, Bvt, St) ->
1630    pat_var(V, Line, Old, Bvt, St);
1631pattern({char,_Line,_C}, _Vt, _Old, _Bvt, St) -> {[],[],St};
1632pattern({integer,_Line,_I}, _Vt, _Old, _Bvt, St) -> {[],[],St};
1633pattern({float,_Line,_F}, _Vt, _Old, _Bvt, St) -> {[],[],St};
1634pattern({atom,Line,A}, _Vt, _Old, _Bvt, St) ->
1635    {[],[],keyword_warning(Line, A, St)};
1636pattern({string,_Line,_S}, _Vt, _Old, _Bvt, St) -> {[],[],St};
1637pattern({nil,_Line}, _Vt, _Old, _Bvt, St) -> {[],[],St};
1638pattern({cons,_Line,H,T}, Vt, Old,  Bvt, St0) ->
1639    {Hvt,Bvt1,St1} = pattern(H, Vt, Old, Bvt, St0),
1640    {Tvt,Bvt2,St2} = pattern(T, Vt, Old, Bvt, St1),
1641    {vtmerge_pat(Hvt, Tvt),vtmerge_pat(Bvt1,Bvt2),St2};
1642pattern({tuple,_Line,Ps}, Vt, Old, Bvt, St) ->
1643    pattern_list(Ps, Vt, Old, Bvt, St);
1644pattern({map,_Line,Ps}, Vt, Old, Bvt, St) ->
1645    pattern_map(Ps, Vt, Old, Bvt, St);
1646pattern({record_index,Line,Name,Field}, _Vt, _Old, _Bvt, St) ->
1647    {Vt1,St1} =
1648        check_record(Line, Name, St,
1649                     fun (Dfs, St1) ->
1650                             pattern_field(Field, Name, Dfs, St1)
1651                     end),
1652    {Vt1,[],St1};
1653pattern({record,Line,Name,Pfs}, Vt, Old, Bvt, St) ->
1654    case maps:find(Name, St#lint.records) of
1655        {ok,{_Line,Fields}} ->
1656            St1 = used_record(Name, St),
1657            St2 = check_multi_field_init(Pfs, Line, Fields, St1),
1658            pattern_fields(Pfs, Name, Fields, Vt, Old, Bvt, St2);
1659        error -> {[],[],add_error(Line, {undefined_record,Name}, St)}
1660    end;
1661pattern({bin,_,Fs}, Vt, Old, Bvt, St) ->
1662    pattern_bin(Fs, Vt, Old, Bvt, St);
1663pattern({op,_Line,'++',{nil,_},R}, Vt, Old, Bvt, St) ->
1664    pattern(R, Vt, Old, Bvt, St);
1665pattern({op,_Line,'++',{cons,Li,{char,_L2,_C},T},R}, Vt, Old, Bvt, St) ->
1666    pattern({op,Li,'++',T,R}, Vt, Old, Bvt, St);    %Char unimportant here
1667pattern({op,_Line,'++',{cons,Li,{integer,_L2,_I},T},R}, Vt, Old, Bvt, St) ->
1668    pattern({op,Li,'++',T,R}, Vt, Old, Bvt, St);    %Weird, but compatible!
1669pattern({op,_Line,'++',{string,_Li,_S},R}, Vt, Old, Bvt, St) ->
1670    pattern(R, Vt, Old, Bvt, St);                   %String unimportant here
1671pattern({match,_Line,Pat1,Pat2}, Vt, Old, Bvt, St0) ->
1672    {Lvt,Bvt1,St1} = pattern(Pat1, Vt, Old, Bvt, St0),
1673    {Rvt,Bvt2,St2} = pattern(Pat2, Vt, Old, Bvt, St1),
1674    St3 = reject_invalid_alias(Pat1, Pat2, Vt, St2),
1675    {vtmerge_pat(Lvt, Rvt),vtmerge_pat(Bvt1,Bvt2),St3};
1676%% Catch legal constant expressions, including unary +,-.
1677pattern(Pat, _Vt, _Old, _Bvt, St) ->
1678    case is_pattern_expr(Pat) of
1679        true -> {[],[],St};
1680        false -> {[],[],add_error(element(2, Pat), illegal_pattern, St)}
1681    end.
1682
1683pattern_list(Ps, Vt, Old, Bvt0, St) ->
1684    foldl(fun (P, {Psvt,Bvt,St0}) ->
1685                  {Pvt,Bvt1,St1} = pattern(P, Vt, Old, Bvt0, St0),
1686                  {vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt,Bvt1),St1}
1687          end, {[],[],St}, Ps).
1688
1689%% Check for '_' initializing no fields.
1690check_multi_field_init(Fs, Line, Fields, St) ->
1691    case
1692        has_wildcard_field(Fs) andalso init_fields(Fs, Line, Fields) =:= []
1693    of
1694        true -> add_error(Line, bad_multi_field_init, St);
1695        false -> St
1696    end.
1697
1698%% reject_invalid_alias(Pat, Expr, Vt, St) -> St'
1699%%  Reject aliases for binary patterns at the top level.
1700%%  Reject aliases for maps patterns at the top level.
1701%%  The variables table (Vt) are for maps checkking.
1702
1703reject_invalid_alias_expr({bin,_,_}=P, {match,_,P0,E}, Vt, St0) ->
1704    St = reject_invalid_alias(P, P0, Vt, St0),
1705    reject_invalid_alias_expr(P, E, Vt, St);
1706reject_invalid_alias_expr({map,_,_}=P, {match,_,P0,E}, Vt, St0) ->
1707    St = reject_invalid_alias(P, P0, Vt, St0),
1708    reject_invalid_alias_expr(P, E, Vt, St);
1709reject_invalid_alias_expr({match,_,_,_}=P, {match,_,P0,E}, Vt, St0) ->
1710    St = reject_invalid_alias(P, P0, Vt, St0),
1711    reject_invalid_alias_expr(P, E, Vt, St);
1712reject_invalid_alias_expr(_, _, _, St) -> St.
1713
1714
1715
1716%% reject_invalid_alias(Pat1, Pat2, St) -> St'
1717%%  Aliases of binary patterns, such as <<A:8>> = <<B:4,C:4>> or even
1718%%  <<A:8>> = <<A:8>>, are not allowed. Traverse the patterns in parallel
1719%%  and generate an error if any binary aliases are found.
1720%%    We generate an error even if is obvious that the overall pattern can't
1721%%  possibly match, for instance, {a,<<A:8>>,c}={x,<<A:8>>} WILL generate an
1722%%  error.
1723%%    Maps should reject unbound variables here.
1724
1725reject_invalid_alias({bin,Line,_}, {bin,_,_}, _, St) ->
1726    add_error(Line, illegal_bin_pattern, St);
1727reject_invalid_alias({map,_Line,Ps1}, {map,_,Ps2}, Vt, St0) ->
1728    Fun = fun ({map_field_exact,L,{var,_,K},_V}, Sti) ->
1729                  case is_var_bound(K,Vt) of
1730                      true ->
1731                          Sti;
1732                      false ->
1733                          add_error(L, {unbound_var,K}, Sti)
1734                  end;
1735              ({map_field_exact,_L,_K,_V}, Sti) ->
1736                  Sti
1737          end,
1738    foldl(Fun, foldl(Fun, St0, Ps1), Ps2);
1739reject_invalid_alias({cons,_,H1,T1}, {cons,_,H2,T2}, Vt, St0) ->
1740    St = reject_invalid_alias(H1, H2, Vt, St0),
1741    reject_invalid_alias(T1, T2, Vt, St);
1742reject_invalid_alias({tuple,_,Es1}, {tuple,_,Es2}, Vt, St) ->
1743    reject_invalid_alias_list(Es1, Es2, Vt, St);
1744reject_invalid_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2}, Vt,
1745                 #lint{records=Recs}=St) ->
1746    case Recs of
1747        #{Name1 := {_Line1,Fields1}, Name2 := {_Line2,Fields2}} ->
1748	    reject_invalid_alias_rec(Pfs1, Pfs2, Fields1, Fields2, Vt, St);
1749        #{} ->
1750	    %% One or more non-existing records. (An error messages has
1751	    %% already been generated, so we are done here.)
1752	    St
1753    end;
1754reject_invalid_alias({match,_,P1,P2}, P, Vt, St0) ->
1755    St = reject_invalid_alias(P1, P, Vt, St0),
1756    reject_invalid_alias(P2, P, Vt, St);
1757reject_invalid_alias(P, {match,_,_,_}=M, Vt, St) ->
1758    reject_invalid_alias(M, P, Vt, St);
1759reject_invalid_alias(_P1, _P2, _Vt, St) -> St.
1760
1761reject_invalid_alias_list([E1|Es1], [E2|Es2], Vt, St0) ->
1762    St = reject_invalid_alias(E1, E2, Vt, St0),
1763    reject_invalid_alias_list(Es1, Es2, Vt, St);
1764reject_invalid_alias_list(_, _, _, St) -> St.
1765
1766reject_invalid_alias_rec(PfsA0, PfsB0, FieldsA0, FieldsB0, Vt, St) ->
1767    %% We treat records as if they have been converted to tuples.
1768    PfsA1 = rbia_field_vars(PfsA0),
1769    PfsB1 = rbia_field_vars(PfsB0),
1770    FieldsA1 = rbia_fields(lists:reverse(FieldsA0), 0, []),
1771    FieldsB1 = rbia_fields(lists:reverse(FieldsB0), 0, []),
1772    FieldsA = sofs:relation(FieldsA1),
1773    PfsA = sofs:relation(PfsA1),
1774    A = sofs:join(FieldsA, 1, PfsA, 1),
1775    FieldsB = sofs:relation(FieldsB1),
1776    PfsB = sofs:relation(PfsB1),
1777    B = sofs:join(FieldsB, 1, PfsB, 1),
1778    C = sofs:join(A, 2, B, 2),
1779    D = sofs:projection({external,fun({_,_,P1,_,P2}) -> {P1,P2} end}, C),
1780    E = sofs:to_external(D),
1781    {Ps1,Ps2} = lists:unzip(E),
1782    reject_invalid_alias_list(Ps1, Ps2, Vt, St).
1783
1784rbia_field_vars(Fs) ->
1785    [{Name,Pat} || {record_field,_,{atom,_,Name},Pat} <- Fs].
1786
1787rbia_fields([{record_field,_,{atom,_,Name},_}|Fs], I, Acc) ->
1788    rbia_fields(Fs, I+1, [{Name,I}|Acc]);
1789rbia_fields([_|Fs], I, Acc) ->
1790    rbia_fields(Fs, I+1, Acc);
1791rbia_fields([], _, Acc) -> Acc.
1792
1793%% is_pattern_expr(Expression) -> boolean().
1794%%  Test if a general expression is a valid pattern expression.
1795
1796is_pattern_expr(Expr) ->
1797    case is_pattern_expr_1(Expr) of
1798	false -> false;
1799	true ->
1800	    %% Expression is syntactically correct - make sure that it
1801	    %% also can be evaluated.
1802	    case erl_eval:partial_eval(Expr) of
1803		{integer,_,_} -> true;
1804		{char,_,_} -> true;
1805		{float,_,_} -> true;
1806		{atom,_,_} -> true;
1807		_ -> false
1808	    end
1809    end.
1810
1811is_pattern_expr_1({char,_Line,_C}) -> true;
1812is_pattern_expr_1({integer,_Line,_I}) -> true;
1813is_pattern_expr_1({float,_Line,_F}) -> true;
1814is_pattern_expr_1({atom,_Line,_A}) -> true;
1815is_pattern_expr_1({tuple,_Line,Es}) ->
1816    all(fun is_pattern_expr/1, Es);
1817is_pattern_expr_1({nil,_Line}) -> true;
1818is_pattern_expr_1({cons,_Line,H,T}) ->
1819    is_pattern_expr_1(H) andalso is_pattern_expr_1(T);
1820is_pattern_expr_1({op,_Line,Op,A}) ->
1821    erl_internal:arith_op(Op, 1) andalso is_pattern_expr_1(A);
1822is_pattern_expr_1({op,_Line,Op,A1,A2}) ->
1823    erl_internal:arith_op(Op, 2) andalso all(fun is_pattern_expr/1, [A1,A2]);
1824is_pattern_expr_1(_Other) -> false.
1825
1826pattern_map(Ps, Vt, Old, Bvt, St) ->
1827    foldl(fun({map_field_assoc,L,_,_}, {Psvt,Bvt0,St0}) ->
1828                  {Psvt,Bvt0,add_error(L, illegal_pattern, St0)};
1829             ({map_field_exact,_L,K,V}, {Psvt,Bvt0,St0}) ->
1830                  St1 = St0#lint{gexpr_context=map_key},
1831                  {Kvt,St2} = gexpr(K, Vt, St1),
1832                  {Vvt,Bvt2,St3} = pattern(V, Vt, Old, Bvt, St2),
1833                  {vtmerge_pat(vtmerge_pat(Kvt, Vvt), Psvt),
1834                   vtmerge_pat(Bvt0, Bvt2),
1835                   St3}
1836          end, {[],[],St}, Ps).
1837
1838%% pattern_bin([Element], VarTable, Old, BinVarTable, State) ->
1839%%           {UpdVarTable,UpdBinVarTable,State}.
1840%%  Check a pattern group. BinVarTable are used binsize variables.
1841
1842pattern_bin(Es, Vt, Old, Bvt0, St0) ->
1843    {_Sz,Esvt,Bvt,St1} = foldl(fun (E, Acc) ->
1844				       pattern_element(E, Vt, Old, Acc)
1845			       end,
1846			       {0,[],Bvt0,St0}, Es),
1847    {Esvt,Bvt,St1}.
1848
1849pattern_element({bin_element,Line,{string,_,_},Size,Ts}=Be, Vt,
1850		Old, {Sz,Esvt,Bvt,St0}=Acc) ->
1851    case good_string_size_type(Size, Ts) of
1852	true ->
1853	    pattern_element_1(Be, Vt, Old, Acc);
1854	false ->
1855	    St = add_error(Line, typed_literal_string, St0),
1856	    {Sz,Esvt,Bvt,St}
1857    end;
1858pattern_element(Be, Vt, Old, Acc) ->
1859    pattern_element_1(Be, Vt, Old, Acc).
1860
1861pattern_element_1({bin_element,Line,E,Sz0,Ts}, Vt, Old, {Size0,Esvt,Bvt,St0}) ->
1862    {Pevt,Bvt1,St1} = pat_bit_expr(E, Old, Bvt, St0),
1863    %% vtmerge or vtmerge_pat doesn't matter here
1864    {Sz1,Szvt,Bvt2,St2} = pat_bit_size(Sz0, vtmerge(Vt, Esvt), Bvt, St1),
1865    {Sz2,Bt,St3} = bit_type(Line, Sz1, Ts, St2),
1866    {Sz3,St4} = bit_size_check(Line, Sz2, Bt, St3),
1867    Sz4 = case {E,Sz3} of
1868	      {{string,_,S},all} -> 8*length(S);
1869	      {_,_} -> Sz3
1870	  end,
1871    {Size1,St5} = add_bit_size(Line, Sz4, Size0, false, St4),
1872    {Size1,vtmerge(Szvt,vtmerge(Pevt, Esvt)),
1873     vtmerge(Bvt2,vtmerge(Bvt, Bvt1)), St5}.
1874
1875good_string_size_type(default, default) ->
1876    true;
1877good_string_size_type(default, Ts) ->
1878    lists:any(fun(utf8) -> true;
1879		 (utf16) -> true;
1880		 (utf32) -> true;
1881		 (_) -> false
1882	      end, Ts);
1883good_string_size_type(_, _) -> false.
1884
1885%% pat_bit_expr(Pattern, OldVarTable, BinVarTable,State) ->
1886%%              {UpdVarTable,UpdBinVarTable,State}.
1887%%  Check pattern bit expression, only allow really valid patterns!
1888
1889pat_bit_expr({var,_,'_'}, _Old, _Bvt, St) -> {[],[],St};
1890pat_bit_expr({var,Ln,V}, Old, Bvt, St) -> pat_var(V, Ln, Old, Bvt, St);
1891pat_bit_expr({string,_,_}, _Old, _Bvt, St) -> {[],[],St};
1892pat_bit_expr({bin,L,_}, _Old, _Bvt, St) ->
1893    {[],[],add_error(L, illegal_pattern, St)};
1894pat_bit_expr(P, _Old, _Bvt, St) ->
1895    case is_pattern_expr(P) of
1896        true -> {[],[],St};
1897        false -> {[],[],add_error(element(2, P), illegal_pattern, St)}
1898    end.
1899
1900%% pat_bit_size(Size, VarTable, BinVarTable, State) ->
1901%%             {Value,UpdVarTable,UpdBinVarTable,State}.
1902%%  Check pattern size expression, only allow really valid sizes!
1903
1904pat_bit_size(default, _Vt, _Bvt, St) -> {default,[],[],St};
1905pat_bit_size({var,Lv,V}, Vt0, Bvt0, St0) ->
1906    {Vt,Bvt,St1} = pat_binsize_var(V, Lv, Vt0, Bvt0, St0),
1907    {unknown,Vt,Bvt,St1};
1908pat_bit_size(Size, Vt0, Bvt0, St0) ->
1909    Line = element(2, Size),
1910    case erl_eval:partial_eval(Size) of
1911        {integer,Line,I} -> {I,[],[],St0};
1912        Expr ->
1913            %% The size is an expression using operators
1914            %% and/or guard BIFs calls. If the expression
1915            %% happens to evaluate to a non-integer value, the
1916            %% pattern will fail to match.
1917            St1 = St0#lint{bvt=Bvt0,gexpr_context=bin_seg_size},
1918            {Vt,#lint{bvt=Bvt}=St2} = gexpr(Size, Vt0, St1),
1919            St3 = St2#lint{bvt=none,gexpr_context=St0#lint.gexpr_context},
1920            St = case is_bit_size_illegal(Expr) of
1921                     true ->
1922                         %% The size is a non-integer literal or a simple
1923                         %% expression that does not evaluate to an
1924                         %% integer value. Issue a warning.
1925                         add_warning(Line, non_integer_bitsize, St3);
1926                     false -> St3
1927                 end,
1928            {unknown,Vt,Bvt,St}
1929    end.
1930
1931is_bit_size_illegal({atom,_,_}) -> true;
1932is_bit_size_illegal({bin,_,_}) -> true;
1933is_bit_size_illegal({cons,_,_,_}) -> true;
1934is_bit_size_illegal({float,_,_}) -> true;
1935is_bit_size_illegal({map,_,_}) -> true;
1936is_bit_size_illegal({nil,_}) -> true;
1937is_bit_size_illegal({tuple,_,_}) -> true;
1938is_bit_size_illegal(_) -> false.
1939
1940%% expr_bin(Line, [Element], VarTable, State, CheckFun) -> {UpdVarTable,State}.
1941%%  Check an expression group.
1942
1943expr_bin(Es, Vt, St0, Check) ->
1944    {_Sz,Esvt,St1} = foldl(fun (E, Acc) -> bin_element(E, Vt, Acc, Check) end,
1945			   {0,[],St0}, Es),
1946    {Esvt,St1}.
1947
1948bin_element({bin_element,Line,E,Sz0,Ts}, Vt, {Size0,Esvt,St0}, Check) ->
1949    {Vt1,St1} = Check(E, Vt, St0),
1950    {Sz1,Vt2,St2} = bit_size(Sz0, Vt, St1, Check),
1951    {Sz2,Bt,St3} = bit_type(Line, Sz1, Ts, St2),
1952    {Sz3,St4} = bit_size_check(Line, Sz2, Bt, St3),
1953    {Size1,St5} = add_bit_size(Line, Sz3, Size0, true, St4),
1954    {Size1,vtmerge([Vt2,Vt1,Esvt]),St5}.
1955
1956bit_size(default, _Vt, St, _Check) -> {default,[],St};
1957bit_size({atom,_Line,all}, _Vt, St, _Check) -> {all,[],St};
1958bit_size(Size, Vt, St, Check) ->
1959    %% Try to safely evaluate Size if constant to get size,
1960    %% otherwise just treat it as an expression.
1961    Info = is_guard_test2_info(St),
1962    case is_gexpr(Size, Info) of
1963        true ->
1964            case erl_eval:partial_eval(Size) of
1965                {integer,_ILn,I} -> {I,[],St};
1966                _Other ->
1967                    {Evt,St1} = Check(Size, Vt, St),
1968                    {unknown,Evt,St1}
1969            end;
1970        false ->
1971            {Evt,St1} = Check(Size, Vt, St),
1972            {unknown,Evt,St1}
1973    end.
1974
1975%% bit_type(Line, Size, TypeList, State) ->  {Size,#bittype,St}.
1976%%  Perform warning check on type and size.
1977
1978bit_type(Line, Size0, Type, St) ->
1979    case erl_bits:set_bit_type(Size0, Type) of
1980        {ok,Size1,Bt} -> {Size1,Bt,St};
1981	{error,What} ->
1982            %% Flag error and generate a default.
1983            {ok,Size1,Bt} = erl_bits:set_bit_type(default, []),
1984            {Size1,Bt,add_error(Line, What, St)}
1985    end.
1986
1987%% bit_size_check(Line, Size, BitType, State) -> {BitSize,State}.
1988%%  Do some checking & warnings on types
1989%%   float == 32 or 64
1990
1991bit_size_check(_Line, unknown, _, St) -> {unknown,St};
1992bit_size_check(_Line, undefined, #bittype{type=Type}, St) ->
1993    true = (Type =:= utf8) or (Type =:= utf16) or (Type =:= utf32), %Assertion.
1994    {undefined,St};
1995bit_size_check(Line, all, #bittype{type=Type}, St) ->
1996    case Type of
1997        binary -> {all,St};
1998        _ -> {unknown,add_error(Line, illegal_bitsize, St)}
1999    end;
2000bit_size_check(Line, Size, #bittype{type=Type,unit=Unit}, St) ->
2001    Sz = Unit * Size,                           %Total number of bits!
2002    St2 = elemtype_check(Line, Type, Sz, St),
2003    {Sz,St2}.
2004
2005elemtype_check(_Line, float, 32, St) -> St;
2006elemtype_check(_Line, float, 64, St) -> St;
2007elemtype_check(Line, float, _Size, St) ->
2008    add_warning(Line, {bad_bitsize,"float"}, St);
2009elemtype_check(_Line, _Type, _Size, St) ->  St.
2010
2011
2012%% add_bit_size(Line, ElementSize, BinSize, Build, State) -> {Size,State}.
2013%%  Add bits to group size.
2014
2015add_bit_size(Line, _Sz1, all, false, St) ->
2016    {all,add_error(Line, unsized_binary_not_at_end, St)};
2017add_bit_size(_Line, _Sz1, all, true, St) ->
2018    {all,St};
2019add_bit_size(_Line, all, _Sz2, _B, St) -> {all,St};
2020add_bit_size(_Line, undefined, _Sz2, _B, St) -> {undefined,St};
2021add_bit_size(_Line, unknown, _Sz2, _B, St) -> {unknown,St};
2022add_bit_size(_Line, _Sz1, undefined, _B, St) -> {unknown,St};
2023add_bit_size(_Line, _Sz1, unknown, _B, St) -> {unknown,St};
2024add_bit_size(_Line, Sz1, Sz2, _B, St) -> {Sz1 + Sz2,St}.
2025
2026%% guard([GuardTest], VarTable, State) ->
2027%%      {UsedVarTable,State}
2028%%  Check a guard, return all variables.
2029
2030%% Disjunction of guard conjunctions
2031guard([L|R], Vt, St0) when is_list(L) ->
2032    {Gvt, St1} = guard_tests(L, Vt, St0),
2033    {Gsvt, St2} = guard(R, vtupdate(Gvt, Vt), St1),
2034    {vtupdate(Gvt, Gsvt),St2};
2035guard(L, Vt, St0) ->
2036    guard_tests(L, Vt, St0).
2037
2038%% guard conjunction
2039guard_tests([G|Gs], Vt, St0) ->
2040    {Gvt,St1} = guard_test(G, Vt, St0),
2041    {Gsvt,St2} = guard_tests(Gs, vtupdate(Gvt, Vt), St1),
2042    {vtupdate(Gvt, Gsvt),St2};
2043guard_tests([], _Vt, St) -> {[],St}.
2044
2045%% guard_test(Test, VarTable, State) ->
2046%%      {UsedVarTable,State'}
2047%%  Check one guard test, returns NewVariables.  We now allow more
2048%%  expressions in guards including the new is_XXX type tests, but
2049%%  only allow the old type tests at the top level.
2050
2051guard_test(G, Vt, St0) ->
2052    St1 = obsolete_guard(G, St0),
2053    guard_test2(G, Vt, St1).
2054
2055%% Specially handle record type test here.
2056guard_test2({call,Line,{atom,Lr,record},[E,A]}, Vt, St0) ->
2057    gexpr({call,Line,{atom,Lr,is_record},[E,A]}, Vt, St0);
2058guard_test2({call,Line,{atom,_La,F},As}=G, Vt, St0) ->
2059    {Asvt,St1} = gexpr_list(As, Vt, St0),       %Always check this.
2060    A = length(As),
2061    case erl_internal:type_test(F, A) of
2062        true when F =/= is_record, A =/= 2 ->
2063	    case no_guard_bif_clash(St1, {F,A}) of
2064		false ->
2065		    {Asvt,add_error(Line, {illegal_guard_local_call,{F,A}}, St1)};
2066		true ->
2067		    {Asvt,St1}
2068	    end;
2069	_ ->
2070	    gexpr(G, Vt, St0)
2071    end;
2072guard_test2(G, Vt, St) ->
2073    %% Everything else is a guard expression.
2074    gexpr(G, Vt, St).
2075
2076%% gexpr(GuardExpression, VarTable, State) ->
2077%%      {UsedVarTable,State'}
2078%%  Check a guard expression, returns NewVariables.
2079
2080gexpr({var,Line,V}, Vt, St) ->
2081    expr_var(V, Line, Vt, St);
2082gexpr({char,_Line,_C}, _Vt, St) -> {[],St};
2083gexpr({integer,_Line,_I}, _Vt, St) -> {[],St};
2084gexpr({float,_Line,_F}, _Vt, St) -> {[],St};
2085gexpr({atom,Line,A}, _Vt, St) ->
2086    {[],keyword_warning(Line, A, St)};
2087gexpr({string,_Line,_S}, _Vt, St) -> {[],St};
2088gexpr({nil,_Line}, _Vt, St) -> {[],St};
2089gexpr({cons,_Line,H,T}, Vt, St) ->
2090    gexpr_list([H,T], Vt, St);
2091gexpr({tuple,_Line,Es}, Vt, St) ->
2092    gexpr_list(Es, Vt, St);
2093gexpr({map,_Line,Es}, Vt, St) ->
2094    map_fields(Es, Vt, check_assoc_fields(Es, St), fun gexpr_list/3);
2095gexpr({map,_Line,Src,Es}, Vt, St) ->
2096    {Svt,St1} = gexpr(Src, Vt, St),
2097    {Fvt,St2} = map_fields(Es, Vt, St1, fun gexpr_list/3),
2098    {vtmerge(Svt, Fvt),St2};
2099gexpr({record_index,Line,Name,Field}, _Vt, St) ->
2100    check_record(Line, Name, St,
2101                 fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end );
2102gexpr({record_field,Line,Rec,Name,Field}, Vt, St0) ->
2103    {Rvt,St1} = gexpr(Rec, Vt, St0),
2104    {Fvt,St2} = check_record(Line, Name, St1,
2105                             fun (Dfs, St) ->
2106                                     record_field(Field, Name, Dfs, St)
2107                             end),
2108    {vtmerge(Rvt, Fvt),St2};
2109gexpr({record,Line,Name,Inits}, Vt, St) ->
2110    check_record(Line, Name, St,
2111                 fun (Dfs, St1) ->
2112                         ginit_fields(Inits, Line, Name, Dfs, Vt, St1)
2113                 end);
2114gexpr({bin,_Line,Fs}, Vt,St) ->
2115    expr_bin(Fs, Vt, St, fun gexpr/3);
2116gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) ->
2117    {Rvt,St1} = gexpr(E, Vt, St0),
2118    {Rvt,exist_record(Ln, Name, St1)};
2119gexpr({call,Line,{atom,_Lr,is_record},[E,R]}, Vt, St0) ->
2120    {Asvt,St1} = gexpr_list([E,R], Vt, St0),
2121    {Asvt,add_error(Line, illegal_guard_expr, St1)};
2122gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
2123      Vt, St0) ->
2124    gexpr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0);
2125gexpr({call,Line,{atom,_Lr,is_record},[E0,{atom,_,_Name},{integer,_,_}]},
2126      Vt, St0) ->
2127    {E,St1} = gexpr(E0, Vt, St0),
2128    case no_guard_bif_clash(St0, {is_record,3}) of
2129	true ->
2130	    {E,St1};
2131	false ->
2132	    {E,add_error(Line, {illegal_guard_local_call,{is_record,3}}, St1)}
2133    end;
2134gexpr({call,Line,{atom,_Lr,is_record},[_,_,_]=Asvt0}, Vt, St0) ->
2135    {Asvt,St1} = gexpr_list(Asvt0, Vt, St0),
2136    {Asvt,add_error(Line, illegal_guard_expr, St1)};
2137gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}=Isr},[_,_,_]=Args},
2138      Vt, St0) ->
2139    gexpr({call,Line,Isr,Args}, Vt, St0);
2140gexpr({call,Line,{atom,_La,F},As}, Vt, St0) ->
2141    {Asvt,St1} = gexpr_list(As, Vt, St0),
2142    A = length(As),
2143    %% BifClash - Function called in guard
2144    case erl_internal:guard_bif(F, A) andalso no_guard_bif_clash(St1,{F,A}) of
2145        true ->
2146	    %% Assert that it is auto-imported.
2147	    true = erl_internal:bif(F, A),
2148	    {Asvt,St1};
2149        false ->
2150	    case is_local_function(St1#lint.locals,{F,A}) orelse
2151		is_imported_function(St1#lint.imports,{F,A}) of
2152		true ->
2153		    {Asvt,add_error(Line, {illegal_guard_local_call,{F,A}}, St1)};
2154		_ ->
2155		    {Asvt,add_error(Line, illegal_guard_expr, St1)}
2156	    end
2157    end;
2158gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Vt, St0) ->
2159    {Asvt,St1} = gexpr_list(As, Vt, St0),
2160    A = length(As),
2161    case erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A) of
2162        true -> {Asvt,St1};
2163        false -> {Asvt,add_error(Line, illegal_guard_expr, St1)}
2164    end;
2165gexpr({op,Line,Op,A}, Vt, St0) ->
2166    {Avt,St1} = gexpr(A, Vt, St0),
2167    case is_gexpr_op(Op, 1) of
2168        true -> {Avt,St1};
2169        false -> {Avt,add_error(Line, illegal_guard_expr, St1)}
2170    end;
2171gexpr({op,_,'andalso',L,R}, Vt, St) ->
2172    gexpr_list([L,R], Vt, St);
2173gexpr({op,_,'orelse',L,R}, Vt, St) ->
2174    gexpr_list([L,R], Vt, St);
2175gexpr({op,Line,Op,L,R}, Vt, St0) ->
2176    {Avt,St1} = gexpr_list([L,R], Vt, St0),
2177    case is_gexpr_op(Op, 2) of
2178        true -> {Avt,St1};
2179        false -> {Avt,add_error(Line, illegal_guard_expr, St1)}
2180    end;
2181%% Everything else is illegal! You could put explicit tests here to
2182%% better error diagnostics.
2183gexpr(E, _Vt, St) ->
2184    {[],add_error(element(2, E), illegal_guard_expr, St)}.
2185
2186%% gexpr_list(Expressions, VarTable, State) ->
2187%%      {UsedVarTable,State'}
2188
2189gexpr_list(Es, Vt, St) ->
2190    foldl(fun (E, {Esvt,St0}) ->
2191                  {Evt,St1} = gexpr(E, Vt, St0),
2192                  {vtmerge(Evt, Esvt),St1}
2193          end, {[],St}, Es).
2194
2195%% is_guard_test(Expression) -> boolean().
2196%%  Test if a general expression is a guard test.
2197%%
2198%%  Note: Only use this function in contexts where there can be
2199%%  no definition of a local function that may override a guard BIF
2200%%  (for example, in the shell).
2201-spec is_guard_test(Expr) -> boolean() when
2202      Expr :: erl_parse:abstract_expr().
2203
2204is_guard_test(E) ->
2205    is_guard_test2(E, {maps:new(),fun(_) -> false end}).
2206
2207%% is_guard_test(Expression, Forms) -> boolean().
2208is_guard_test(Expression, Forms) ->
2209    is_guard_test(Expression, Forms, fun(_) -> false end).
2210
2211
2212%% is_guard_test(Expression, Forms, IsOverridden) -> boolean().
2213%%  Test if a general expression is a guard test.
2214%%
2215%%  IsOverridden({Name,Arity}) should return 'true' if Name/Arity is
2216%%  a local or imported function in the module. If the abstract code has
2217%%  passed through erl_expand_records, any call without an explicit
2218%%  module is to a local function, so IsOverridden can be defined as:
2219%%
2220%%    fun(_) -> true end
2221%%
2222-spec is_guard_test(Expr, Forms, IsOverridden) -> boolean() when
2223      Expr :: erl_parse:abstract_expr(),
2224      Forms :: [erl_parse:abstract_form() | erl_parse:form_info()],
2225      IsOverridden :: fun((fa()) -> boolean()).
2226
2227is_guard_test(Expression, Forms, IsOverridden) ->
2228    RecordAttributes = [A || A = {attribute, _, record, _D} <- Forms],
2229    St0 = foldl(fun(Attr0, St1) ->
2230                        Attr = set_file(Attr0, "none"),
2231                        attribute_state(Attr, St1)
2232                end, start(), RecordAttributes),
2233    is_guard_test2(set_file(Expression, "nofile"),
2234		   {St0#lint.records,IsOverridden}).
2235
2236%% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean().
2237is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, Info) ->
2238    is_gexpr({call,Line,{atom,Lr,is_record},[E,A]}, Info);
2239is_guard_test2({call,_Line,{atom,_La,Test},As}=Call, {_,IsOverridden}=Info) ->
2240    A = length(As),
2241    not IsOverridden({Test,A}) andalso
2242	case erl_internal:type_test(Test, A) of
2243	    true -> is_gexpr_list(As, Info);
2244	    false -> is_gexpr(Call, Info)
2245	end;
2246is_guard_test2(G, Info) ->
2247    %%Everything else is a guard expression.
2248    is_gexpr(G, Info).
2249
2250%% is_guard_expr(Expression) -> boolean().
2251%%  Test if an expression is a guard expression.
2252
2253is_guard_expr(E) -> is_gexpr(E, {[],fun({_,_}) -> false end}).
2254
2255is_gexpr({var,_L,_V}, _Info) -> true;
2256is_gexpr({char,_L,_C}, _Info) -> true;
2257is_gexpr({integer,_L,_I}, _Info) -> true;
2258is_gexpr({float,_L,_F}, _Info) -> true;
2259is_gexpr({atom,_L,_A}, _Info) -> true;
2260is_gexpr({string,_L,_S}, _Info) -> true;
2261is_gexpr({nil,_L}, _Info) -> true;
2262is_gexpr({cons,_L,H,T}, Info) -> is_gexpr_list([H,T], Info);
2263is_gexpr({tuple,_L,Es}, Info) -> is_gexpr_list(Es, Info);
2264is_gexpr({map,_L,Es}, Info) ->
2265    is_map_fields(Es, Info);
2266is_gexpr({map,_L,Src,Es}, Info) ->
2267    is_gexpr(Src, Info) andalso is_map_fields(Es, Info);
2268is_gexpr({record_index,_L,_Name,Field}, Info) ->
2269    is_gexpr(Field, Info);
2270is_gexpr({record_field,_L,Rec,_Name,Field}, Info) ->
2271    is_gexpr_list([Rec,Field], Info);
2272is_gexpr({record,L,Name,Inits}, Info) ->
2273    is_gexpr_fields(Inits, L, Name, Info);
2274is_gexpr({bin,_L,Fs}, Info) ->
2275    all(fun ({bin_element,_Line,E,Sz,_Ts}) ->
2276                is_gexpr(E, Info) and (Sz =:= default orelse is_gexpr(Sz, Info))
2277        end, Fs);
2278is_gexpr({call,_L,{atom,_Lf,F},As}, {_,IsOverridden}=Info) ->
2279    A = length(As),
2280    not IsOverridden({F,A}) andalso erl_internal:guard_bif(F, A)
2281	andalso is_gexpr_list(As, Info);
2282is_gexpr({call,_L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Info) ->
2283    A = length(As),
2284    (erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A))
2285        andalso is_gexpr_list(As, Info);
2286is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, Info) ->
2287    is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, Info);
2288is_gexpr({op,_L,Op,A}, Info) ->
2289    is_gexpr_op(Op, 1) andalso is_gexpr(A, Info);
2290is_gexpr({op,_L,'andalso',A1,A2}, Info) ->
2291    is_gexpr_list([A1,A2], Info);
2292is_gexpr({op,_L,'orelse',A1,A2}, Info) ->
2293    is_gexpr_list([A1,A2], Info);
2294is_gexpr({op,_L,Op,A1,A2}, Info) ->
2295    is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], Info);
2296is_gexpr(_Other, _Info) -> false.
2297
2298is_gexpr_op(Op, A) ->
2299    try erl_internal:op_type(Op, A) of
2300        arith -> true;
2301        bool  -> true;
2302        comp  -> true;
2303	list  -> false;
2304	send  -> false
2305    catch _:_ -> false
2306    end.
2307
2308is_gexpr_list(Es, Info) -> all(fun (E) -> is_gexpr(E, Info) end, Es).
2309
2310is_map_fields([{Tag,_,K,V}|Fs], Info) when Tag =:= map_field_assoc;
2311                                           Tag =:= map_field_exact ->
2312    is_gexpr(K, Info) andalso
2313    is_gexpr(V, Info) andalso
2314    is_map_fields(Fs, Info);
2315is_map_fields([], _Info) -> true;
2316is_map_fields(_T, _Info) -> false.
2317
2318is_gexpr_fields(Fs, L, Name, {RDs,_}=Info) ->
2319    IFs = case maps:find(Name, RDs) of
2320              {ok,{_Line,Fields}} -> Fs ++ init_fields(Fs, L, Fields);
2321              error  -> Fs
2322          end,
2323    all(fun ({record_field,_Lf,_Name,V}) -> is_gexpr(V, Info);
2324            (_Other) -> false end, IFs).
2325
2326%% exprs(Sequence, VarTable, State) ->
2327%%      {UsedVarTable,State'}
2328%%  Check a sequence of expressions, return all variables.
2329
2330exprs([E|Es], Vt, St0) ->
2331    {Evt,St1} = expr(E, Vt, St0),
2332    {Esvt,St2} = exprs(Es, vtupdate(Evt, Vt), St1),
2333    {vtupdate(Evt, Esvt),St2};
2334exprs([], _Vt, St) -> {[],St}.
2335
2336%% expr(Expression, VarTable, State) ->
2337%%      {UsedVarTable,State'}
2338%%  Check an expression, returns NewVariables. Assume naive users and
2339%%  mark illegally exported variables, e.g. from catch, as unsafe to better
2340%%  show why unbound.
2341
2342expr({var,Line,V}, Vt, St) ->
2343    expr_var(V, Line, Vt, St);
2344expr({char,_Line,_C}, _Vt, St) -> {[],St};
2345expr({integer,_Line,_I}, _Vt, St) -> {[],St};
2346expr({float,_Line,_F}, _Vt, St) -> {[],St};
2347expr({atom,Line,A}, _Vt, St) ->
2348    {[],keyword_warning(Line, A, St)};
2349expr({string,_Line,_S}, _Vt, St) -> {[],St};
2350expr({nil,_Line}, _Vt, St) -> {[],St};
2351expr({cons,_Line,H,T}, Vt, St) ->
2352    expr_list([H,T], Vt, St);
2353expr({lc,_Line,E,Qs}, Vt, St) ->
2354    handle_comprehension(E, Qs, Vt, St);
2355expr({bc,_Line,E,Qs}, Vt, St) ->
2356    handle_comprehension(E, Qs, Vt, St);
2357expr({tuple,_Line,Es}, Vt, St) ->
2358    expr_list(Es, Vt, St);
2359expr({map,_Line,Es}, Vt, St) ->
2360    map_fields(Es, Vt, check_assoc_fields(Es, St), fun expr_list/3);
2361expr({map,_Line,Src,Es}, Vt, St) ->
2362    {Svt,St1} = expr(Src, Vt, St),
2363    {Fvt,St2} = map_fields(Es, Vt, St1, fun expr_list/3),
2364    {vtupdate(Svt, Fvt),St2};
2365expr({record_index,Line,Name,Field}, _Vt, St) ->
2366    check_record(Line, Name, St,
2367                 fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end);
2368expr({record,Line,Name,Inits}, Vt, St) ->
2369    check_record(Line, Name, St,
2370                 fun (Dfs, St1) ->
2371                         init_fields(Inits, Line, Name, Dfs, Vt, St1)
2372                 end);
2373expr({record_field,Line,Rec,Name,Field}, Vt, St0) ->
2374    {Rvt,St1} = record_expr(Line, Rec, Vt, St0),
2375    {Fvt,St2} = check_record(Line, Name, St1,
2376                             fun (Dfs, St) ->
2377                                     record_field(Field, Name, Dfs, St)
2378                             end),
2379    {vtmerge(Rvt, Fvt),St2};
2380expr({record,Line,Rec,Name,Upds}, Vt, St0) ->
2381    {Rvt,St1} = record_expr(Line, Rec, Vt, St0),
2382    {Usvt,St2} = check_record(Line, Name, St1,
2383                          fun (Dfs, St) ->
2384                                  update_fields(Upds, Name, Dfs, Vt, St)
2385                          end ),
2386    case has_wildcard_field(Upds) of
2387        true -> {[],add_error(Line, {wildcard_in_update,Name}, St2)};
2388        false -> {vtmerge(Rvt, Usvt),St2}
2389    end;
2390expr({bin,_Line,Fs}, Vt, St) ->
2391    expr_bin(Fs, Vt, St, fun expr/3);
2392expr({block,_Line,Es}, Vt, St) ->
2393    %% Unfold block into a sequence.
2394    exprs(Es, Vt, St);
2395expr({'if',Line,Cs}, Vt, St) ->
2396    icrt_clauses(Cs, {'if',Line}, Vt, St);
2397expr({'case',Line,E,Cs}, Vt, St0) ->
2398    {Evt,St1} = expr(E, Vt, St0),
2399    {Cvt,St2} = icrt_clauses(Cs, {'case',Line}, vtupdate(Evt, Vt), St1),
2400    {vtmerge(Evt, Cvt),St2};
2401expr({'receive',Line,Cs}, Vt, St) ->
2402    icrt_clauses(Cs, {'receive',Line}, Vt, St);
2403expr({'receive',Line,Cs,To,ToEs}, Vt, St0) ->
2404    %% Are variables from the timeout expression visible in the clauses? NO!
2405    {Tvt,St1} = expr(To, Vt, St0),
2406    {Tevt,St2} = exprs(ToEs, Vt, St1),
2407    {Cvt,St3} = icrt_clauses(Cs, Vt, St2),
2408    %% Csvts = [vtnew(Tevt, Vt)|Cvt],           %This is just NEW variables!
2409    Csvts = [Tevt|Cvt],
2410    Rvt = icrt_export(Csvts, Vt, {'receive',Line}, St3),
2411    {vtmerge([Tvt,Tevt,Rvt]),St3};
2412expr({'fun',Line,Body}, Vt, St) ->
2413    %%No one can think funs export!
2414    case Body of
2415        {clauses,Cs} ->
2416            fun_clauses(Cs, Vt, St);
2417        {function,record_info,2} ->
2418            %% It is illegal to call record_info/2 with unknown arguments.
2419            {[],add_error(Line, illegal_record_info, St)};
2420        {function,F,A} ->
2421	    %% BifClash - Fun expression
2422            %% N.B. Only allows BIFs here as well, NO IMPORTS!!
2423            case ((not is_local_function(St#lint.locals,{F,A})) andalso
2424		  (erl_internal:bif(F, A) andalso
2425		   (not is_autoimport_suppressed(St#lint.no_auto,{F,A})))) of
2426                true -> {[],St};
2427                false -> {[],call_function(Line, F, A, St)}
2428            end;
2429	{function,M,F,A} when is_atom(M), is_atom(F), is_integer(A) ->
2430	    %% Compatibility with pre-R15 abstract format.
2431	    {[],St};
2432	{function,M,F,A} ->
2433	    %% New in R15.
2434	    expr_list([M,F,A], Vt, St)
2435    end;
2436expr({named_fun,_,'_',Cs}, Vt, St) ->
2437    fun_clauses(Cs, Vt, St);
2438expr({named_fun,Line,Name,Cs}, Vt, St0) ->
2439    Nvt0 = [{Name,{bound,unused,[Line]}}],
2440    St1 = shadow_vars(Nvt0, Vt, 'named fun', St0),
2441    Nvt1 = vtupdate(vtsubtract(Vt, Nvt0), Nvt0),
2442    {Csvt,St2} = fun_clauses(Cs, Nvt1, St1),
2443    {_,St3} = check_unused_vars(vtupdate(Csvt, Nvt0), [], St2),
2444    {vtold(Csvt, Vt),St3};
2445expr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) ->
2446    {Rvt,St1} = expr(E, Vt, St0),
2447    {Rvt,exist_record(Ln, Name, St1)};
2448expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
2449      Vt, St0) ->
2450    expr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0);
2451expr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,is_record}]},As}, Vt, St) ->
2452    expr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,is_record}},As}, Vt, St);
2453expr({call,Line,{remote,_Lr,{atom,_Lm,M},{atom,Lf,F}},As}, Vt, St0) ->
2454    St1 = keyword_warning(Lf, F, St0),
2455    St2 = check_remote_function(Line, M, F, As, St1),
2456    St3 = check_module_name(M, Line, St2),
2457    expr_list(As, Vt, St3);
2458expr({call,Line,{remote,_Lr,M,F},As}, Vt, St0) ->
2459    St1 = keyword_warning(Line, M, St0),
2460    St2 = keyword_warning(Line, F, St1),
2461    St3 = case M of
2462              {atom,Lm,Mod} ->
2463                  check_module_name(Mod, Lm, St2);
2464              _ ->
2465                  St2
2466          end,
2467    expr_list([M,F|As], Vt, St3);
2468expr({call,Line,{atom,La,F},As}, Vt, St0) ->
2469    St1 = keyword_warning(La, F, St0),
2470    {Asvt,St2} = expr_list(As, Vt, St1),
2471    A = length(As),
2472    IsLocal = is_local_function(St2#lint.locals,{F,A}),
2473    IsAutoBif = erl_internal:bif(F, A),
2474    AutoSuppressed = is_autoimport_suppressed(St2#lint.no_auto,{F,A}),
2475    Warn = is_warn_enabled(bif_clash, St2) and (not bif_clash_specifically_disabled(St2,{F,A})),
2476    Imported = imported(F, A, St2),
2477    case ((not IsLocal) andalso (Imported =:= no) andalso
2478	  IsAutoBif andalso (not AutoSuppressed)) of
2479        true ->
2480	    St3 = deprecated_function(Line, erlang, F, As, St2),
2481	    {Asvt,St3};
2482        false ->
2483            {Asvt,case Imported of
2484                      {yes,M} ->
2485                          St3 = check_remote_function(Line, M, F, As, St2),
2486                          U0 = St3#lint.usage,
2487                          Imp = ordsets:add_element({{F,A},M},U0#usage.imported),
2488                          St3#lint{usage=U0#usage{imported = Imp}};
2489                      no ->
2490			  case {F,A} of
2491			      {record_info,2} ->
2492                                  check_record_info_call(Line,La,As,St2);
2493                              N ->
2494				  %% BifClash - function call
2495				  %% Issue these warnings/errors even if it's a recursive call
2496				  St3 = if
2497					    (not AutoSuppressed) andalso IsAutoBif andalso Warn ->
2498						case erl_internal:old_bif(F,A) of
2499						    true ->
2500							add_error
2501							  (Line,
2502							   {call_to_redefined_old_bif, {F,A}},
2503							   St2);
2504						    false ->
2505							add_warning
2506							  (Line,
2507							   {call_to_redefined_bif, {F,A}},
2508							   St2)
2509						end;
2510					    true ->
2511						St2
2512					end,
2513				  %% ...but don't lint recursive calls
2514				  if
2515				      N =:= St3#lint.func ->
2516					  St3;
2517				      true ->
2518					  call_function(Line, F, A, St3)
2519				  end
2520                          end
2521                  end}
2522    end;
2523expr({call,Line,F,As}, Vt, St0) ->
2524    St = warn_invalid_call(Line,F,St0),
2525    expr_list([F|As], Vt, St);                  %They see the same variables
2526expr({'try',Line,Es,Scs,Ccs,As}, Vt, St0) ->
2527    %% Currently, we don't allow any exports because later
2528    %% passes cannot handle exports in combination with 'after'.
2529    {Evt0,St1} = exprs(Es, Vt, St0),
2530    TryLine = {'try',Line},
2531    Uvt = vtunsafe(TryLine, Evt0, Vt),
2532    Evt1 = vtupdate(Uvt, Evt0),
2533    {Sccs,St2} = try_clauses(Scs, Ccs, TryLine,
2534                             vtupdate(Evt1, Vt), St1),
2535    Rvt0 = Sccs,
2536    Rvt1 = vtupdate(vtunsafe(TryLine, Rvt0, Vt), Rvt0),
2537    Evt2 = vtmerge(Evt1, Rvt1),
2538    {Avt0,St} = exprs(As, vtupdate(Evt2, Vt), St2),
2539    Avt1 = vtupdate(vtunsafe(TryLine, Avt0, Vt), Avt0),
2540    Avt = vtmerge(Evt2, Avt1),
2541    {Avt,St};
2542expr({'catch',Line,E}, Vt, St0) ->
2543    %% No new variables added, flag new variables as unsafe.
2544    {Evt,St} = expr(E, Vt, St0),
2545    {vtupdate(vtunsafe({'catch',Line}, Evt, Vt), Evt),St};
2546expr({match,_Line,P,E}, Vt, St0) ->
2547    {Evt,St1} = expr(E, Vt, St0),
2548    {Pvt,Bvt,St2} = pattern(P, vtupdate(Evt, Vt), St1),
2549    St = reject_invalid_alias_expr(P, E, Vt, St2),
2550    {vtupdate(Bvt, vtmerge(Evt, Pvt)),St};
2551%% No comparison or boolean operators yet.
2552expr({op,_Line,_Op,A}, Vt, St) ->
2553    expr(A, Vt, St);
2554expr({op,Line,Op,L,R}, Vt, St0) when Op =:= 'orelse'; Op =:= 'andalso' ->
2555    {Evt1,St1} = expr(L, Vt, St0),
2556    Vt1 = vtupdate(Evt1, Vt),
2557    {Evt2,St2} = expr(R, Vt1, St1),
2558    Evt3 = vtupdate(vtunsafe({Op,Line}, Evt2, Vt1), Evt2),
2559    {vtmerge(Evt1, Evt3),St2};
2560expr({op,_Line,_Op,L,R}, Vt, St) ->
2561    expr_list([L,R], Vt, St);                   %They see the same variables
2562%% The following are not allowed to occur anywhere!
2563expr({remote,Line,_M,_F}, _Vt, St) ->
2564    {[],add_error(Line, illegal_expr, St)}.
2565
2566%% expr_list(Expressions, Variables, State) ->
2567%%      {UsedVarTable,State}
2568
2569expr_list(Es, Vt, St) ->
2570    foldl(fun (E, {Esvt,St0}) ->
2571                  {Evt,St1} = expr(E, Vt, St0),
2572                  {vtmerge_pat(Evt, Esvt),St1}
2573          end, {[],St}, Es).
2574
2575record_expr(Line, Rec, Vt, St0) ->
2576    St1 = warn_invalid_record(Line, Rec, St0),
2577    expr(Rec, Vt, St1).
2578
2579check_assoc_fields([{map_field_exact,Line,_,_}|Fs], St) ->
2580    check_assoc_fields(Fs, add_error(Line, illegal_map_construction, St));
2581check_assoc_fields([{map_field_assoc,_,_,_}|Fs], St) ->
2582    check_assoc_fields(Fs, St);
2583check_assoc_fields([], St) ->
2584    St.
2585
2586map_fields([{Tag,_,K,V}|Fs], Vt, St, F) when Tag =:= map_field_assoc;
2587                                             Tag =:= map_field_exact ->
2588    {Pvt,St2} = F([K,V], Vt, St),
2589    {Vts,St3} = map_fields(Fs, Vt, St2, F),
2590    {vtupdate(Pvt, Vts),St3};
2591map_fields([], _, St, _) ->
2592  {[],St}.
2593
2594%% warn_invalid_record(Line, Record, State0) -> State
2595%% Adds warning if the record is invalid.
2596
2597warn_invalid_record(Line, R, St) ->
2598    case is_valid_record(R) of
2599        true -> St;
2600        false -> add_warning(Line, invalid_record, St)
2601    end.
2602
2603%% is_valid_record(Record) -> boolean().
2604
2605is_valid_record(Rec) ->
2606    case Rec of
2607        {char, _, _} -> false;
2608        {integer, _, _} -> false;
2609        {float, _, _} -> false;
2610        {atom, _, _} -> false;
2611        {string, _, _} -> false;
2612        {cons, _, _, _} -> false;
2613        {nil, _} -> false;
2614        {lc, _, _, _} -> false;
2615        {record_index, _, _, _} -> false;
2616        {'fun', _, _} -> false;
2617        {named_fun, _, _, _} -> false;
2618        _ -> true
2619    end.
2620
2621%% warn_invalid_call(Line, Call, State0) -> State
2622%% Adds warning if the call is invalid.
2623
2624warn_invalid_call(Line, F, St) ->
2625    case is_valid_call(F) of
2626        true -> St;
2627        false -> add_warning(Line, invalid_call, St)
2628    end.
2629
2630%% is_valid_call(Call) -> boolean().
2631
2632is_valid_call(Call) ->
2633    case Call of
2634        {char, _, _} -> false;
2635        {integer, _, _} -> false;
2636        {float, _, _} -> false;
2637        {string, _, _} -> false;
2638        {cons, _, _, _} -> false;
2639        {nil, _} -> false;
2640        {lc, _, _, _} -> false;
2641        {record_index, _, _, _} -> false;
2642        {tuple, _, Exprs} when length(Exprs) =/= 2 -> false;
2643        _ -> true
2644    end.
2645
2646%% record_def(Line, RecordName, [RecField], State) -> State.
2647%%  Add a record definition if it does not already exist. Normalise
2648%%  so that all fields have explicit initial value.
2649
2650record_def(Line, Name, Fs0, St0) ->
2651    case is_map_key(Name, St0#lint.records) of
2652        true -> add_error(Line, {redefine_record,Name}, St0);
2653        false ->
2654            {Fs1,St1} = def_fields(normalise_fields(Fs0), Name, St0),
2655            St2 = St1#lint{records=maps:put(Name, {Line,Fs1},
2656                                              St1#lint.records)},
2657            Types = [T || {typed_record_field, _, T} <- Fs0],
2658            check_type({type, nowarn(), product, Types}, St2)
2659    end.
2660
2661%% def_fields([RecDef], RecordName, State) -> {[DefField],State}.
2662%%  Check (normalised) fields for duplicates.  Return unduplicated
2663%%  record and set State.
2664
2665def_fields(Fs0, Name, St0) ->
2666    foldl(fun ({record_field,Lf,{atom,La,F},V}, {Fs,St}) ->
2667                  case exist_field(F, Fs) of
2668                      true -> {Fs,add_error(Lf, {redefine_field,Name,F}, St)};
2669                      false ->
2670                          St1 = St#lint{recdef_top = true},
2671                          {_,St2} = expr(V, [], St1),
2672                          %% Warnings and errors found are kept, but
2673                          %% updated calls, records, etc. are discarded.
2674                          St3 = St1#lint{warnings = St2#lint.warnings,
2675                                         errors = St2#lint.errors,
2676                                         called = St2#lint.called,
2677                                         recdef_top = false},
2678                          %% This is one way of avoiding a loop for
2679                          %% "recursive" definitions.
2680                          NV = case St2#lint.errors =:= St1#lint.errors of
2681                                   true -> V;
2682                                   false -> {atom,La,undefined}
2683                               end,
2684                          {[{record_field,Lf,{atom,La,F},NV}|Fs],St3}
2685                  end
2686          end, {[],St0}, Fs0).
2687
2688%% normalise_fields([RecDef]) -> [Field].
2689%%  Normalise the field definitions to always have a default value. If
2690%%  none has been given then use 'undefined'.
2691%%  Also, strip type information from typed record fields.
2692
2693normalise_fields(Fs) ->
2694    map(fun ({record_field,Lf,Field}) ->
2695		{record_field,Lf,Field,{atom,Lf,undefined}};
2696	    ({typed_record_field,{record_field,Lf,Field},_Type}) ->
2697		{record_field,Lf,Field,{atom,Lf,undefined}};
2698	    ({typed_record_field,Field,_Type}) ->
2699		Field;
2700            (F) -> F end, Fs).
2701
2702%% exist_record(Line, RecordName, State) -> State.
2703%%  Check if a record exists.  Set State.
2704
2705exist_record(Line, Name, St) ->
2706    case is_map_key(Name, St#lint.records) of
2707        true -> used_record(Name, St);
2708        false -> add_error(Line, {undefined_record,Name}, St)
2709    end.
2710
2711%% check_record(Line, RecordName, State, CheckFun) ->
2712%%      {UpdVarTable, State}.
2713%%  The generic record checking function, first checks that the record
2714%%  exists then calls the specific check function.  N.B. the check
2715%%  function can safely assume that the record exists.
2716%%
2717%%  The check function is called:
2718%%      CheckFun(RecordDefFields, State)
2719%%  and must return
2720%%      {UpdatedVarTable,State}
2721
2722check_record(Line, Name, St, CheckFun) ->
2723    case maps:find(Name, St#lint.records) of
2724        {ok,{_Line,Fields}} -> CheckFun(Fields, used_record(Name, St));
2725        error -> {[],add_error(Line, {undefined_record,Name}, St)}
2726    end.
2727
2728used_record(Name, #lint{usage=Usage}=St) ->
2729    UsedRecs = gb_sets:add_element(Name, Usage#usage.used_records),
2730    St#lint{usage = Usage#usage{used_records=UsedRecs}}.
2731
2732%%% Record check functions.
2733
2734%% check_fields([ChkField], RecordName, [RecDefField], VarTable, State, CheckFun) ->
2735%%      {UpdVarTable,State}.
2736
2737check_fields(Fs, Name, Fields, Vt, St0, CheckFun) ->
2738    {_SeenFields,Uvt,St1} =
2739        foldl(fun (Field, {Sfsa,Vta,Sta}) ->
2740                      {Sfsb,{Vtb,Stb}} = check_field(Field, Name, Fields,
2741                                                     Vt, Sta, Sfsa, CheckFun),
2742                      {Sfsb,vtmerge_pat(Vta, Vtb),Stb}
2743              end, {[],[],St0}, Fs),
2744    {Uvt,St1}.
2745
2746check_field({record_field,Lf,{atom,La,F},Val}, Name, Fields,
2747            Vt, St, Sfs, CheckFun) ->
2748    case member(F, Sfs) of
2749        true -> {Sfs,{[],add_error(Lf, {redefine_field,Name,F}, St)}};
2750        false ->
2751            {[F|Sfs],
2752             case find_field(F, Fields) of
2753                 {ok,_I} -> CheckFun(Val, Vt, St);
2754                 error -> {[],add_error(La, {undefined_field,Name,F}, St)}
2755             end}
2756    end;
2757check_field({record_field,_Lf,{var,La,'_'=F},Val}, _Name, _Fields,
2758            Vt, St, Sfs, CheckFun) ->
2759    case member(F, Sfs) of
2760        true -> {Sfs,{[],add_error(La, bad_multi_field_init, St)}};
2761        false -> {[F|Sfs],CheckFun(Val, Vt, St)}
2762    end;
2763check_field({record_field,_Lf,{var,La,V},_Val}, Name, _Fields,
2764            Vt, St, Sfs, _CheckFun) ->
2765    {Sfs,{Vt,add_error(La, {field_name_is_variable,Name,V}, St)}}.
2766
2767%% pattern_field(Field, RecordName, [RecDefField], State) ->
2768%%      {UpdVarTable,State}.
2769%%  Test if record RecordName has field Field. Set State.
2770
2771pattern_field({atom,La,F}, Name, Fields, St) ->
2772    case find_field(F, Fields) of
2773        {ok,_I} -> {[],St};
2774        error -> {[],add_error(La, {undefined_field,Name,F}, St)}
2775    end.
2776
2777%% pattern_fields([PatField],RecordName,[RecDefField],
2778%%                VarTable,Old,Bvt,State) ->
2779%%      {UpdVarTable,UpdBinVarTable,State}.
2780
2781pattern_fields(Fs, Name, Fields, Vt0, Old, Bvt, St0) ->
2782    CheckFun = fun (Val, Vt, St) -> pattern(Val, Vt, Old, Bvt, St) end,
2783    {_SeenFields,Uvt,Bvt1,St1} =
2784        foldl(fun (Field, {Sfsa,Vta,Bvt1,Sta}) ->
2785                      case check_field(Field, Name, Fields,
2786                                       Vt0, Sta, Sfsa, CheckFun) of
2787                          {Sfsb,{Vtb,Stb}} ->
2788                              {Sfsb,vtmerge_pat(Vta, Vtb),[],Stb};
2789                          {Sfsb,{Vtb,Bvt2,Stb}} ->
2790                              {Sfsb,vtmerge_pat(Vta, Vtb),
2791                               vtmerge_pat(Bvt1,Bvt2),Stb}
2792                      end
2793              end, {[],[],[],St0}, Fs),
2794    {Uvt,Bvt1,St1}.
2795
2796%% record_field(Field, RecordName, [RecDefField], State) ->
2797%%      {UpdVarTable,State}.
2798%%  Test if record RecordName has field Field. Set State.
2799
2800record_field({atom,La,F}, Name, Fields, St) ->
2801    case find_field(F, Fields) of
2802        {ok,_I} -> {[],St};
2803        error -> {[],add_error(La, {undefined_field,Name,F}, St)}
2804    end.
2805
2806%% init_fields([InitField], InitLine, RecordName, [DefField], VarTable, State) ->
2807%%      {UpdVarTable,State}.
2808%% ginit_fields([InitField], InitLine, RecordName, [DefField], VarTable, State) ->
2809%%      {UpdVarTable,State}.
2810%%  Check record initialisation. Explicit initialisations are checked
2811%%  as is, while default values are checked only if there are no
2812%%  explicit inititialisations of the fields. Be careful not to
2813%%  duplicate warnings (and possibly errors, but def_fields
2814%%  substitutes 'undefined' for bogus inititialisations) from when the
2815%%  record definitions were checked. Usage of records, imports, and
2816%%  functions is collected.
2817
2818init_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
2819    {Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun expr/3),
2820    Defs = init_fields(Ifs, Line, Dfs),
2821    {_,St2} = check_fields(Defs, Name, Dfs, Vt1, St1, fun expr/3),
2822    {Vt1,St1#lint{usage = St2#lint.usage}}.
2823
2824ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
2825    {Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun gexpr/3),
2826    Defs = init_fields(Ifs, Line, Dfs),
2827    St2 = St1#lint{errors = []},
2828    {_,St3} = check_fields(Defs, Name, Dfs, Vt1, St2, fun gexpr/3),
2829    #lint{usage = Usage, errors = Errors} = St3,
2830    IllErrs = [E || {_File,{_Line,erl_lint,illegal_guard_expr}}=E <- Errors],
2831    St4 = St1#lint{usage = Usage, errors = IllErrs ++ St1#lint.errors},
2832    {Vt1,St4}.
2833
2834%% Default initializations to be carried out
2835init_fields(Ifs, Line, Dfs) ->
2836    [ {record_field,Lf,{atom,La,F},copy_expr(Di, Line)} ||
2837        {record_field,Lf,{atom,La,F},Di} <- Dfs,
2838        not exist_field(F, Ifs) ].
2839
2840%% update_fields(UpdFields, RecordName, RecDefFields, VarTable, State) ->
2841%%      {UpdVarTable,State}
2842
2843update_fields(Ufs, Name, Dfs, Vt, St) ->
2844    check_fields(Ufs, Name, Dfs, Vt, St, fun expr/3).
2845
2846%% exist_field(FieldName, [Field]) -> boolean().
2847%%  Find a record field in a field list.
2848
2849exist_field(F, [{record_field,_Lf,{atom,_La,F},_Val}|_Fs]) -> true;
2850exist_field(F, [_|Fs]) -> exist_field(F, Fs);
2851exist_field(_F, []) -> false.
2852
2853%% find_field(FieldName, [Field]) -> {ok,Val} | error.
2854%%  Find a record field in a field list.
2855
2856find_field(_F, [{record_field,_Lf,{atom,_La,_F},Val}|_Fs]) -> {ok,Val};
2857find_field(F, [_|Fs]) -> find_field(F, Fs);
2858find_field(_F, []) -> error.
2859
2860%% type_def(Attr, Line, TypeName, PatField, Args, State) -> State.
2861%%    Attr :: 'type' | 'opaque'
2862%% Checks that a type definition is valid.
2863
2864-dialyzer({no_match, type_def/6}).
2865
2866type_def(Attr, Line, TypeName, ProtoType, Args, St0) ->
2867    TypeDefs = St0#lint.types,
2868    Arity = length(Args),
2869    TypePair = {TypeName, Arity},
2870    Info = #typeinfo{attr = Attr, line = Line},
2871    StoreType =
2872        fun(St) ->
2873                NewDefs = maps:put(TypePair, Info, TypeDefs),
2874                CheckType = {type, nowarn(), product, [ProtoType|Args]},
2875                check_type(CheckType, St#lint{types=NewDefs})
2876        end,
2877    case is_default_type(TypePair) of
2878        true ->
2879            case is_obsolete_builtin_type(TypePair) of
2880                true -> StoreType(St0);
2881                false ->
2882                     case is_newly_introduced_builtin_type(TypePair) of
2883                         %% allow some types just for bootstrapping
2884                         true ->
2885                             Warn = {new_builtin_type, TypePair},
2886                             St1 = add_warning(Line, Warn, St0),
2887                             StoreType(St1);
2888                         false ->
2889                             add_error(Line, {builtin_type, TypePair}, St0)
2890                     end
2891            end;
2892        false ->
2893            case is_map_key(TypePair, TypeDefs) of
2894                true ->
2895                    add_error(Line, {redefine_type, TypePair}, St0);
2896                false ->
2897                    St1 = case
2898                              Attr =:= opaque andalso
2899                              is_underspecified(ProtoType, Arity)
2900                          of
2901                              true ->
2902                                  Warn = {underspecified_opaque, TypePair},
2903                                  add_warning(Line, Warn, St0);
2904                              false -> St0
2905                          end,
2906                    StoreType(St1)
2907	    end
2908    end.
2909
2910is_underspecified({type,_,term,[]}, 0) -> true;
2911is_underspecified({type,_,any,[]}, 0) -> true;
2912is_underspecified(_ProtType, _Arity) -> false.
2913
2914check_type(Types, St) ->
2915    {SeenVars, St1} = check_type(Types, maps:new(), St),
2916    maps:fold(fun(Var, {seen_once, Line}, AccSt) ->
2917		      case atom_to_list(Var) of
2918			  "_"++_ -> AccSt;
2919			  _ -> add_error(Line, {singleton_typevar, Var}, AccSt)
2920		      end;
2921		 (_Var, seen_multiple, AccSt) ->
2922		      AccSt
2923	      end, St1, SeenVars).
2924
2925check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) ->
2926    check_type(Type, SeenVars, St);
2927check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
2928	   SeenVars, St00) ->
2929    St0 = check_module_name(Mod, L, St00),
2930    St = deprecated_type(L, Mod, Name, Args, St0),
2931    CurrentMod = St#lint.module,
2932    case Mod =:= CurrentMod of
2933	true -> check_type({user_type, L, Name, Args}, SeenVars, St);
2934	false ->
2935	    lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
2936				check_type(T, AccSeenVars, AccSt)
2937			end, {SeenVars, St}, Args)
2938    end;
2939check_type({integer, _L, _}, SeenVars, St) -> {SeenVars, St};
2940check_type({atom, _L, _}, SeenVars, St) -> {SeenVars, St};
2941check_type({var, _L, '_'}, SeenVars, St) -> {SeenVars, St};
2942check_type({var, L, Name}, SeenVars, St) ->
2943    NewSeenVars =
2944	case maps:find(Name, SeenVars) of
2945	    {ok, {seen_once, _}} -> maps:put(Name, seen_multiple, SeenVars);
2946	    {ok, seen_multiple} -> SeenVars;
2947	    error -> maps:put(Name, {seen_once, L}, SeenVars)
2948	end,
2949    {NewSeenVars, St};
2950check_type({type, L, bool, []}, SeenVars, St) ->
2951    {SeenVars, add_warning(L, {renamed_type, bool, boolean}, St)};
2952check_type({type, L, 'fun', [Dom, Range]}, SeenVars, St) ->
2953    St1 =
2954	case Dom of
2955	    {type, _, product, _} -> St;
2956	    {type, _, any} -> St;
2957	    _ -> add_error(L, {type_syntax, 'fun'}, St)
2958	end,
2959    check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St1);
2960check_type({type, L, range, [From, To]}, SeenVars, St) ->
2961    St1 =
2962	case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
2963	    {{integer, _, X}, {integer, _, Y}} when X < Y -> St;
2964	    _ -> add_error(L, {type_syntax, range}, St)
2965	end,
2966    {SeenVars, St1};
2967check_type({type, _L, map, any}, SeenVars, St) ->
2968    {SeenVars, St};
2969check_type({type, _L, map, Pairs}, SeenVars, St) ->
2970    lists:foldl(fun(Pair, {AccSeenVars, AccSt}) ->
2971			check_type(Pair, AccSeenVars, AccSt)
2972		end, {SeenVars, St}, Pairs);
2973check_type({type, _L, map_field_assoc, [Dom, Range]}, SeenVars, St) ->
2974    check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St);
2975check_type({type, _L, tuple, any}, SeenVars, St) -> {SeenVars, St};
2976check_type({type, _L, any}, SeenVars, St) -> {SeenVars, St};
2977check_type({type, L, binary, [Base, Unit]}, SeenVars, St) ->
2978    St1 =
2979	case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
2980	    {{integer, _, BaseVal},
2981	     {integer, _, UnitVal}} when BaseVal >= 0, UnitVal >= 0 -> St;
2982	    _ -> add_error(L, {type_syntax, binary}, St)
2983	end,
2984    {SeenVars, St1};
2985check_type({type, L, record, [Name|Fields]}, SeenVars, St) ->
2986    case Name of
2987	{atom, _, Atom} ->
2988	    St1 = used_record(Atom, St),
2989	    check_record_types(L, Atom, Fields, SeenVars, St1);
2990	_ -> {SeenVars, add_error(L, {type_syntax, record}, St)}
2991    end;
2992check_type({type, _L, Tag, Args}, SeenVars, St) when Tag =:= product;
2993                                                     Tag =:= union;
2994                                                     Tag =:= tuple ->
2995    lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
2996			check_type(T, AccSeenVars, AccSt)
2997		end, {SeenVars, St}, Args);
2998check_type({type, La, TypeName, Args}, SeenVars, St) ->
2999    #lint{module = Module, types=Types} = St,
3000    Arity = length(Args),
3001    TypePair = {TypeName, Arity},
3002    Obsolete = (is_warn_enabled(deprecated_type, St)
3003                andalso obsolete_builtin_type(TypePair)),
3004    St1 = case Obsolete of
3005              {deprecated, Repl, _} when element(1, Repl) =/= Module ->
3006                  case maps:find(TypePair, Types) of
3007                      {ok, _} ->
3008                          used_type(TypePair, La, St);
3009                      error ->
3010                          {deprecated, Replacement, Rel} = Obsolete,
3011                          Tag = deprecated_builtin_type,
3012                          W = {Tag, TypePair, Replacement, Rel},
3013                          add_warning(La, W, St)
3014                end;
3015            _ -> St
3016        end,
3017    check_type({type, nowarn(), product, Args}, SeenVars, St1);
3018check_type({user_type, L, TypeName, Args}, SeenVars, St) ->
3019    Arity = length(Args),
3020    TypePair = {TypeName, Arity},
3021    St1 = used_type(TypePair, L, St),
3022    lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
3023			check_type(T, AccSeenVars, AccSt)
3024		end, {SeenVars, St1}, Args);
3025check_type([{typed_record_field,Field,_T}|_], SeenVars, St) ->
3026    {SeenVars, add_error(element(2, Field), old_abstract_code, St)};
3027check_type(I, SeenVars, St) ->
3028    case erl_eval:partial_eval(I) of
3029        {integer,_ILn,_Integer} -> {SeenVars, St};
3030        _Other ->
3031            {SeenVars, add_error(element(2, I), {type_syntax, integer}, St)}
3032    end.
3033
3034check_record_types(Line, Name, Fields, SeenVars, St) ->
3035    case maps:find(Name, St#lint.records) of
3036        {ok,{_L,DefFields}} ->
3037	    case lists:all(fun({type, _, field_type, _}) -> true;
3038			      (_) -> false
3039			   end, Fields) of
3040		true ->
3041		    check_record_types(Fields, Name, DefFields, SeenVars, St, []);
3042		false ->
3043		    {SeenVars, add_error(Line, {type_syntax, record}, St)}
3044	    end;
3045        error ->
3046	    {SeenVars, add_error(Line, {undefined_record, Name}, St)}
3047    end.
3048
3049check_record_types([{type, _, field_type, [{atom, AL, FName}, Type]}|Left],
3050		   Name, DefFields, SeenVars, St, SeenFields) ->
3051    %% Check that the field name is valid
3052    St1 = case exist_field(FName, DefFields) of
3053	      true -> St;
3054	      false -> add_error(AL, {undefined_field, Name, FName}, St)
3055	  end,
3056    %% Check for duplicates
3057    St2 = case ordsets:is_element(FName, SeenFields) of
3058	      true -> add_error(AL, {redefine_field, Name, FName}, St1);
3059	      false -> St1
3060	  end,
3061    %% Check Type
3062    {NewSeenVars, St3} = check_type(Type, SeenVars, St2),
3063    NewSeenFields = ordsets:add_element(FName, SeenFields),
3064    check_record_types(Left, Name, DefFields, NewSeenVars, St3, NewSeenFields);
3065check_record_types([], _Name, _DefFields, SeenVars, St, _SeenFields) ->
3066    {SeenVars, St}.
3067
3068used_type(TypePair, L, #lint{usage = Usage, file = File} = St) ->
3069    OldUsed = Usage#usage.used_types,
3070    UsedTypes = maps:put(TypePair, erl_anno:set_file(File, L), OldUsed),
3071    St#lint{usage=Usage#usage{used_types=UsedTypes}}.
3072
3073is_default_type({Name, NumberOfTypeVariables}) ->
3074    erl_internal:is_type(Name, NumberOfTypeVariables).
3075
3076is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false.
3077
3078is_obsolete_builtin_type(TypePair) ->
3079    obsolete_builtin_type(TypePair) =/= no.
3080
3081%% To keep Dialyzer silent...
3082obsolete_builtin_type({1, 255}) ->
3083    {deprecated, {2, 255}, ""};
3084obsolete_builtin_type({Name, A}) when is_atom(Name), is_integer(A) -> no.
3085
3086%% spec_decl(Line, Fun, Types, State) -> State.
3087
3088spec_decl(Line, MFA0, TypeSpecs, St00 = #lint{specs = Specs, module = Mod}) ->
3089    MFA = case MFA0 of
3090	      {F, Arity} -> {Mod, F, Arity};
3091	      {_M, _F, Arity} -> MFA0
3092	  end,
3093    St0 = check_module_name(element(1, MFA), Line, St00),
3094    St1 = St0#lint{specs = maps:put(MFA, Line, Specs)},
3095    case is_map_key(MFA, Specs) of
3096	true -> add_error(Line, {redefine_spec, MFA0}, St1);
3097	false ->
3098            case MFA of
3099                {Mod, _, _} ->
3100                    check_specs(TypeSpecs, spec_wrong_arity, Arity, St1);
3101                _ ->
3102                    add_error(Line, {bad_module, MFA}, St1)
3103            end
3104    end.
3105
3106%% callback_decl(Line, Fun, Types, State) -> State.
3107
3108callback_decl(Line, MFA0, TypeSpecs,
3109	      St0 = #lint{callbacks = Callbacks, module = Mod}) ->
3110    case MFA0 of
3111        {M, _F, _A} ->
3112            St1 = check_module_name(M, Line, St0),
3113            add_error(Line, {bad_callback, MFA0}, St1);
3114        {F, Arity} ->
3115            MFA = {Mod, F, Arity},
3116            St1 = St0#lint{callbacks = maps:put(MFA, Line, Callbacks)},
3117            case is_map_key(MFA, Callbacks) of
3118                true -> add_error(Line, {redefine_callback, MFA0}, St1);
3119                false -> check_specs(TypeSpecs, callback_wrong_arity,
3120                                     Arity, St1)
3121            end
3122    end.
3123
3124%% optional_callbacks(Line, FAs, State) -> State.
3125
3126optional_callbacks(Line, Term, St0) ->
3127    try true = is_fa_list(Term), Term of
3128        FAs ->
3129            optional_cbs(Line, FAs, St0)
3130    catch
3131        _:_ ->
3132            St0 % ignore others
3133    end.
3134
3135optional_cbs(_Line, [], St) ->
3136    St;
3137optional_cbs(Line, [{F,A}|FAs], St0) ->
3138    #lint{optional_callbacks = OptionalCbs, module = Mod} = St0,
3139    MFA = {Mod, F, A},
3140    St1 = St0#lint{optional_callbacks = maps:put(MFA, Line, OptionalCbs)},
3141    St2 = case is_map_key(MFA, OptionalCbs) of
3142              true ->
3143                  add_error(Line, {redefine_optional_callback, {F,A}}, St1);
3144              false ->
3145                  St1
3146          end,
3147    optional_cbs(Line, FAs, St2).
3148
3149is_fa_list([E|L]) -> is_fa(E) andalso is_fa_list(L);
3150is_fa_list([]) -> true;
3151is_fa_list(_) -> false.
3152
3153is_fa({FuncName, Arity})
3154  when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true;
3155is_fa(_) -> false.
3156
3157check_module_name(M, Line, St) ->
3158    case is_latin1_name(M) of
3159        true -> St;
3160        false ->
3161            add_error(Line, non_latin1_module_unsupported, St)
3162    end.
3163
3164is_latin1_name(Name) ->
3165    io_lib:latin1_char_list(atom_to_list(Name)).
3166
3167check_specs([FunType|Left], ETag, Arity, St0) ->
3168    {FunType1, CTypes} =
3169	case FunType of
3170	    {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} ->
3171		Types0 = [T || {type, _, constraint, [_, T]} <- Cs],
3172		{FT, lists:append(Types0)};
3173	    {type, _, 'fun', _} = FT -> {FT, []}
3174	end,
3175    {type, L, 'fun', [{type, _, product, D}, _]} = FunType1,
3176    SpecArity = length(D),
3177    St1 = case Arity =:= SpecArity of
3178	      true -> St0;
3179	      false -> %% Cannot happen if called from the compiler.
3180                  add_error(L, ETag, St0)
3181	  end,
3182    St2 = check_type({type, nowarn(), product, [FunType1|CTypes]}, St1),
3183    check_specs(Left, ETag, Arity, St2);
3184check_specs([], _ETag, _Arity, St) ->
3185    St.
3186
3187nowarn() ->
3188    A0 = erl_anno:new(0),
3189    A1 = erl_anno:set_generated(true, A0),
3190    erl_anno:set_file("", A1).
3191
3192check_specs_without_function(#lint{module=Mod,defined=Funcs,specs=Specs}=St) ->
3193    Fun = fun({M, F, A}, Line, AccSt) when M =:= Mod ->
3194                  FA = {F, A},
3195		  case gb_sets:is_element(FA, Funcs) of
3196		      true -> AccSt;
3197		      false -> add_error(Line, {spec_fun_undefined, FA}, AccSt)
3198		  end;
3199	     ({_M, _F, _A}, _Line, AccSt) -> AccSt
3200	  end,
3201    maps:fold(Fun, St, Specs).
3202
3203%% This generates warnings for functions without specs; if the user has
3204%% specified both options, we do not generate the same warnings twice.
3205check_functions_without_spec(Forms, St0) ->
3206    case is_warn_enabled(missing_spec_all, St0) of
3207	true ->
3208	    add_missing_spec_warnings(Forms, St0, all);
3209	false ->
3210	    case is_warn_enabled(missing_spec, St0) of
3211		true ->
3212		    add_missing_spec_warnings(Forms, St0, exported);
3213		false ->
3214		    St0
3215	    end
3216    end.
3217
3218add_missing_spec_warnings(Forms, St0, Type) ->
3219    Specs = [{F,A} || {_M,F,A} <- maps:keys(St0#lint.specs)],
3220    Warns = %% functions + line numbers for which we should warn
3221	case Type of
3222	    all ->
3223		[{FA,L} || {function,L,F,A,_} <- Forms,
3224			   not lists:member(FA = {F,A}, Specs)];
3225	    exported ->
3226		Exps0 = gb_sets:to_list(St0#lint.exports) -- pseudolocals(),
3227                Exps = Exps0 -- Specs,
3228		[{FA,L} || {function,L,F,A,_} <- Forms,
3229			   member(FA = {F,A}, Exps)]
3230	end,
3231    foldl(fun ({FA,L}, St) ->
3232		  add_warning(L, {missing_spec,FA}, St)
3233	  end, St0, Warns).
3234
3235check_unused_types(Forms, St) ->
3236    case is_warn_enabled(unused_type, St) of
3237        true -> check_unused_types_1(Forms, St);
3238        false -> St
3239    end.
3240
3241check_unused_types_1(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) ->
3242    case [File || {attribute,_L,file,{File,_Line}} <- Forms] of
3243	[FirstFile|_] ->
3244	    D = Usage#usage.used_types,
3245	    L = gb_sets:to_list(ExpTs) ++ maps:keys(D),
3246	    UsedTypes = gb_sets:from_list(L),
3247	    FoldFun =
3248                fun({{record, _}=_Type, 0}, _, AccSt) ->
3249                        AccSt; % Before Erlang/OTP 19.0
3250                   (Type, #typeinfo{line = FileLine}, AccSt) ->
3251                        case loc(FileLine, AccSt) of
3252			    {FirstFile, _} ->
3253				case gb_sets:is_member(Type, UsedTypes) of
3254				    true -> AccSt;
3255				    false ->
3256					Warn = {unused_type,Type},
3257					add_warning(FileLine, Warn, AccSt)
3258				end;
3259			    _ ->
3260				%% No warns about unused types in include files
3261				AccSt
3262			end
3263		end,
3264	    maps:fold(FoldFun, St, Ts);
3265	[] ->
3266	    St
3267    end.
3268
3269check_local_opaque_types(St) ->
3270    #lint{types=Ts, exp_types=ExpTs} = St,
3271    FoldFun =
3272        fun(_Type, #typeinfo{attr = type}, AccSt) ->
3273                AccSt;
3274           (Type, #typeinfo{attr = opaque, line = FileLine}, AccSt) ->
3275                case gb_sets:is_element(Type, ExpTs) of
3276                    true -> AccSt;
3277                    false ->
3278                        Warn = {not_exported_opaque,Type},
3279                        add_warning(FileLine, Warn, AccSt)
3280                end
3281        end,
3282    maps:fold(FoldFun, St, Ts).
3283
3284check_dialyzer_attribute(Forms, St0) ->
3285    Vals = [{L,V} ||
3286               {attribute,L,dialyzer,Val} <- Forms,
3287               V0 <- lists:flatten([Val]),
3288               V <- case V0 of
3289                        {O,F} ->
3290                            [{A,B} ||
3291                                A <- lists:flatten([O]),
3292                                B <- lists:flatten([F])];
3293                        T -> [T]
3294                    end],
3295    {Wellformed, Bad} =
3296        lists:partition(fun ({_,{Option,FA}}) when is_atom(Option) ->
3297                                is_fa(FA);
3298                            ({_,Option}) when is_atom(Option) -> true;
3299                            (_) -> false
3300                        end, Vals),
3301    St1 = foldl(fun ({L,Term}, St) ->
3302		  add_error(L, {bad_dialyzer_attribute,Term}, St)
3303	  end, St0, Bad),
3304    DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()),
3305    Fun = fun ({L,{Option,FA}}, St) ->
3306                  case is_function_dialyzer_option(Option) of
3307                      true ->
3308                          case lists:member(FA, DefFunctions) of
3309                              true -> St;
3310                              false ->
3311                                  add_error(L, {undefined_function,FA}, St)
3312                          end;
3313                      false ->
3314                          add_error(L, {bad_dialyzer_option,Option}, St)
3315                  end;
3316              ({L,Option}, St) ->
3317                  case is_module_dialyzer_option(Option) of
3318                      true -> St;
3319                      false ->
3320                          add_error(L, {bad_dialyzer_option,Option}, St)
3321                  end
3322          end,
3323    foldl(Fun, St1, Wellformed).
3324
3325is_function_dialyzer_option(nowarn_function) -> true;
3326is_function_dialyzer_option(Option) ->
3327    is_module_dialyzer_option(Option).
3328
3329is_module_dialyzer_option(Option) ->
3330    lists:member(Option,
3331                 [no_return,no_unused,no_improper_lists,no_fun_app,
3332                  no_match,no_opaque,no_fail_call,no_contracts,
3333                  no_behaviours,no_undefined_callbacks,unmatched_returns,
3334                  error_handling,race_conditions,no_missing_calls,
3335                  specdiffs,overspecs,underspecs,unknown]).
3336
3337%% try_catch_clauses(Scs, Ccs, In, ImportVarTable, State) ->
3338%%      {UpdVt,State}.
3339
3340try_clauses(Scs, Ccs, In, Vt, St0) ->
3341    {Csvt0,St1} = icrt_clauses(Scs, Vt, St0),
3342    St2 = St1#lint{in_try_head=true},
3343    {Csvt1,St3} = icrt_clauses(Ccs, Vt, St2),
3344    Csvt = Csvt0 ++ Csvt1,
3345    UpdVt = icrt_export(Csvt, Vt, In, St3),
3346    {UpdVt,St3#lint{in_try_head=false}}.
3347
3348%% icrt_clauses(Clauses, In, ImportVarTable, State) ->
3349%%      {UpdVt,State}.
3350
3351icrt_clauses(Cs, In, Vt, St0) ->
3352    {Csvt,St1} = icrt_clauses(Cs, Vt, St0),
3353    UpdVt = icrt_export(Csvt, Vt, In, St1),
3354    {UpdVt,St1}.
3355
3356%% icrt_clauses(Clauses, ImportVarTable, State) ->
3357%%      {NewVts,State}.
3358
3359icrt_clauses(Cs, Vt, St) ->
3360    mapfoldl(fun (C, St0) -> icrt_clause(C, Vt, St0) end, St, Cs).
3361
3362icrt_clause({clause,_Line,H,G,B}, Vt0, St0) ->
3363    Vt1 = taint_stack_var(Vt0, H, St0),
3364    {Hvt,Binvt,St1} = head(H, Vt1, St0),
3365    Vt2 = vtupdate(Hvt, Binvt),
3366    Vt3 = taint_stack_var(Vt2, H, St0),
3367    {Gvt,St2} = guard(G, vtupdate(Vt3, Vt0), St1#lint{in_try_head=false}),
3368    Vt4 = vtupdate(Gvt, Vt2),
3369    {Bvt,St3} = exprs(B, vtupdate(Vt4, Vt0), St2),
3370    {vtupdate(Bvt, Vt4),St3}.
3371
3372taint_stack_var(Vt, Pat, #lint{in_try_head=true}) ->
3373    [{tuple,_,[_,_,{var,_,Stk}]}] = Pat,
3374    case Stk of
3375        '_' ->
3376            Vt;
3377        _ ->
3378            lists:map(fun({V,{bound,Used,Lines}}) when V =:= Stk ->
3379                              {V,{stacktrace,Used,Lines}};
3380                         (B) ->
3381                              B
3382                      end, Vt)
3383    end;
3384taint_stack_var(Vt, _Pat, #lint{in_try_head=false}) ->
3385    Vt.
3386
3387icrt_export(Vts, Vt, {Tag,Attrs}, St) ->
3388    {_File,Loc} = loc(Attrs, St),
3389    icrt_export(lists:merge(Vts), Vt, {Tag,Loc}, length(Vts), []).
3390
3391icrt_export([{V,{{export,_},_,_}}|Vs0], [{V,{{export,_}=S0,_,Ls}}|Vt],
3392            In, I, Acc) ->
3393    %% V was an exported variable and has been used in an expression in at least
3394    %% one clause. Its state needs to be merged from all clauses to silence any
3395    %% exported var warning already emitted.
3396    {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0),
3397    S = foldl(fun ({_,{S1,_,_}}, AccS) -> merge_state(AccS, S1) end, S0, VVs),
3398    icrt_export(Vs, Vt, In, I, [{V,{S,used,Ls}}|Acc]);
3399icrt_export([{V,_}|Vs0], [{V,{_,_,Ls}}|Vt], In, I, Acc) ->
3400    %% V was either unsafe or bound and has now been reused. It may also have
3401    %% been an export but as it was not matched by the previous clause, it means
3402    %% it has been changed to 'bound' in at least one clause because it was used
3403    %% in a pattern.
3404    Vs = lists:dropwhile(fun ({K,_}) -> K =:= V end, Vs0),
3405    icrt_export(Vs, Vt, In, I, [{V,{bound,used,Ls}}|Acc]);
3406icrt_export([{V1,_}|_]=Vs, [{V2,_}|Vt], In, I, Acc) when V1 > V2 ->
3407    %% V2 was already in scope and has not been reused in any clause.
3408    icrt_export(Vs, Vt, In, I, Acc);
3409icrt_export([{V,_}|_]=Vs0, Vt, In, I, Acc) ->
3410    %% V is a new variable.
3411    {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0),
3412    F = fun ({_,{S,U,Ls}}, {AccI,AccS0,AccLs0}) ->
3413                AccS = case {S,AccS0} of
3414                           {{unsafe,_},{unsafe,_}} ->
3415                               %% V was found unsafe in a previous clause, mark
3416                               %% it as unsafe for the whole parent expression.
3417                               {unsafe,In};
3418                           {{unsafe,_},_} ->
3419                               %% V was unsafe in a clause, keep that state and
3420                               %% generalize it to the whole expression if it
3421                               %% is found unsafe in another one.
3422                               S;
3423                           _ ->
3424                               %% V is either bound or exported, keep original
3425                               %% state.
3426                               AccS0
3427                       end,
3428                AccLs = case U of
3429                            used -> AccLs0;
3430                            unused -> merge_lines(AccLs0, Ls)
3431                        end,
3432                {AccI + 1,AccS,AccLs}
3433        end,
3434    %% Initial state is exported from the current expression.
3435    {Count,S1,Ls} = foldl(F, {0,{export,In},[]}, VVs),
3436    S = case Count of
3437            I ->
3438                %% V was found in all clauses, keep computed state.
3439                S1;
3440            _ ->
3441                %% V was not bound in some clauses, mark as unsafe.
3442                {unsafe,In}
3443        end,
3444    U = case Ls of [] -> used; _ -> unused end,
3445    icrt_export(Vs, Vt, In, I, [{V,{S,U,Ls}}|Acc]);
3446icrt_export([], _, _, _, Acc) ->
3447    reverse(Acc).
3448
3449handle_comprehension(E, Qs, Vt0, St0) ->
3450    {Vt1, Uvt, St1} = lc_quals(Qs, Vt0, St0),
3451    {Evt,St2} = expr(E, Vt1, St1),
3452    Vt2 = vtupdate(Evt, Vt1),
3453    %% Shadowed global variables.
3454    {_,St3} = check_old_unused_vars(Vt2, Uvt, St2),
3455    %% There may be local variables in Uvt that are not global.
3456    {_,St4} = check_unused_vars(Uvt, Vt0, St3),
3457    %% Local variables that have not been shadowed.
3458    {_,St} = check_unused_vars(Vt2, Vt0, St4),
3459    Vt3 = vtmerge(vtsubtract(Vt2, Uvt), Uvt),
3460    %% Don't export local variables.
3461    Vt4 = vtold(Vt3, Vt0),
3462    %% Forget about old variables which were not used as well as unsafe
3463    %% variables, preventing them from being marked as used and bound by
3464    %% icrt_export/4.
3465    Vt = vt_no_unsafe(vt_no_unused(Vt4)),
3466    {Vt, St}.
3467
3468%% lc_quals(Qualifiers, ImportVarTable, State) ->
3469%%      {VarTable,ShadowedVarTable,State}
3470%%  Test list comprehension qualifiers, return all variables. Allow
3471%%  filters to be both guard tests and general expressions, but the errors
3472%%  will be for expressions. Return the complete updated vartable including
3473%%  local variables and all updates. ShadowVarTable contains the state of
3474%%  each shadowed variable. All variable states of variables in ImportVarTable
3475%%  that have been shadowed are included in ShadowVarTable. In addition, all
3476%%  shadowed variables that are not included in ImportVarTable are included
3477%%  in ShadowVarTable (these are local variables that are not global variables).
3478
3479lc_quals(Qs, Vt0, St0) ->
3480    OldRecDef = St0#lint.recdef_top,
3481    {Vt,Uvt,St} = lc_quals(Qs, Vt0, [], St0#lint{recdef_top = false}),
3482    {Vt,Uvt,St#lint{recdef_top = OldRecDef}}.
3483
3484lc_quals([{generate,_Line,P,E} | Qs], Vt0, Uvt0, St0) ->
3485    {Vt,Uvt,St} = handle_generator(P,E,Vt0,Uvt0,St0),
3486    lc_quals(Qs, Vt, Uvt, St);
3487lc_quals([{b_generate,_Line,P,E} | Qs], Vt0, Uvt0, St0) ->
3488    St1 = handle_bitstring_gen_pat(P,St0),
3489    {Vt,Uvt,St} = handle_generator(P,E,Vt0,Uvt0,St1),
3490    lc_quals(Qs, Vt, Uvt, St);
3491lc_quals([F|Qs], Vt, Uvt, St0) ->
3492    Info = is_guard_test2_info(St0),
3493    {Fvt,St1} = case is_guard_test2(F, Info) of
3494		    true -> guard_test(F, Vt, St0);
3495		    false -> expr(F, Vt, St0)
3496		end,
3497    lc_quals(Qs, vtupdate(Fvt, Vt), Uvt, St1);
3498lc_quals([], Vt, Uvt, St) ->
3499    {Vt, Uvt, St}.
3500
3501is_guard_test2_info(#lint{records=RDs,locals=Locals,imports=Imports}) ->
3502    {RDs,fun(FA) ->
3503		 is_local_function(Locals, FA) orelse
3504		     is_imported_function(Imports, FA)
3505	 end}.
3506
3507handle_generator(P,E,Vt,Uvt,St0) ->
3508    {Evt,St1} = expr(E, Vt, St0),
3509    %% Forget variables local to E immediately.
3510    Vt1 = vtupdate(vtold(Evt, Vt), Vt),
3511    {_, St2} = check_unused_vars(Evt, Vt, St1),
3512    {Pvt,Binvt,St3} = pattern(P, Vt1, [], [], St2),
3513    %% Have to keep fresh variables separated from used variables somehow
3514    %% in order to handle for example X = foo(), [X || <<X:X>> <- bar()].
3515    %%                                1           2      2 1
3516    Vt2 = vtupdate(Pvt, Vt1),
3517    St4 = shadow_vars(Binvt, Vt1, generate, St3),
3518    Svt = vtold(Vt2, Binvt),
3519    {_, St5} = check_old_unused_vars(Svt, Uvt, St4),
3520    NUvt = vtupdate(vtnew(Svt, Uvt), Uvt),
3521    Vt3 = vtupdate(vtsubtract(Vt2, Binvt), Binvt),
3522    {Vt3,NUvt,St5}.
3523
3524handle_bitstring_gen_pat({bin,_,Segments=[_|_]},St) ->
3525    case lists:last(Segments) of
3526        {bin_element,Line,_,default,Flags} when is_list(Flags) ->
3527            case member(binary, Flags) orelse member(bytes, Flags)
3528              orelse member(bits, Flags) orelse member(bitstring, Flags) of
3529                true ->
3530                    add_error(Line, unsized_binary_in_bin_gen_pattern, St);
3531                false ->
3532                    St
3533            end;
3534        _ ->
3535            St
3536    end;
3537handle_bitstring_gen_pat(_,St) ->
3538    St.
3539
3540%% fun_clauses(Clauses, ImportVarTable, State) ->
3541%%      {UsedVars, State}.
3542%%  Fun's cannot export any variables.
3543
3544%% It is an error if variable is bound inside a record definition
3545%% unless it was introduced in a fun or an lc. Only if pat_var finds
3546%% such variables can the correct line number be given.
3547
3548fun_clauses(Cs, Vt, St) ->
3549    OldRecDef = St#lint.recdef_top,
3550    {Bvt,St2} = foldl(fun (C, {Bvt0, St0}) ->
3551                              {Cvt,St1} = fun_clause(C, Vt, St0),
3552                              {vtmerge(Cvt, Bvt0),St1}
3553                      end, {[],St#lint{recdef_top = false}}, Cs),
3554    Uvt = vt_no_unsafe(vt_no_unused(vtold(Bvt, Vt))),
3555    {Uvt,St2#lint{recdef_top = OldRecDef}}.
3556
3557fun_clause({clause,_Line,H,G,B}, Vt0, St0) ->
3558    {Hvt,Binvt,St1} = head(H, Vt0, [], St0), % No imported pattern variables
3559    Vt1 = vtupdate(Hvt, Vt0),
3560    St2 = shadow_vars(Binvt, Vt0, 'fun', St1),
3561    Vt2 = vtupdate(vtsubtract(Vt1, Binvt), Binvt),
3562    {Gvt,St3} = guard(G, Vt2, St2),
3563    Vt3 = vtupdate(Gvt, Vt2),
3564    {Bvt,St4} = exprs(B, Vt3, St3),
3565    Cvt = vtupdate(Bvt, Vt3),
3566    %% Check new local variables.
3567    {_, St5} = check_unused_vars(Cvt, Vt0, St4),
3568    %% Check all shadowing variables.
3569    Svt = vtold(Vt1, Binvt),
3570    {_, St6} = check_old_unused_vars(Cvt, Svt, St5),
3571    Vt4 = vtmerge(Svt, vtsubtract(Cvt, Svt)),
3572    {vtold(Vt4, Vt0),St6}.
3573
3574%% In the variable table we store information about variables. The
3575%% information is a tuple {State,Usage,Lines}, the variables state and
3576%% usage. A variable can be in the following states:
3577%%
3578%% bound                everything is normal
3579%% {export,From}        variable has been exported
3580%% {unsafe,In}          variable is unsafe
3581%%
3582%% The usage information has the following form:
3583%%
3584%% used         variable has been used
3585%% unused       variable has been bound but not used
3586%%
3587%% Lines is a list of line numbers where the variable was bound.
3588%%
3589%% Report variable errors/warnings as soon as possible and then change
3590%% the state to ok. This simplifies the code and reports errors only
3591%% once. Having the usage information like this makes it easy too when
3592%% merging states.
3593
3594%% For keeping track of which variables are bound, ordsets are used.
3595%% In order to be able to give warnings about unused variables, a
3596%% possible value is {bound, unused, [Line]}. The usual value when a
3597%% variable is used is {bound, used, [Line]}. An exception occurs for
3598%% variables in the size position in a bin element in a pattern.
3599%% Currently, such a variable is never matched out, always used, and
3600%% therefore it makes no sense to warn for "variable imported in
3601%% match".
3602
3603%% For storing the variable table we use the orddict module.
3604%% We know an empty set is [].
3605
3606%% pat_var(Variable, LineNo, VarTable, State) -> {UpdVarTable,State}
3607%%  A pattern variable has been found. Handle errors and warnings. Return
3608%%  all variables as bound so errors and warnings are only reported once.
3609%% Bvt "shadows" Vt here, which is necessary in order to separate uses of
3610%% shadowed and shadowing variables. See also pat_binsize_var.
3611
3612pat_var(V, Line, Vt, Bvt, St) ->
3613    case orddict:find(V, Bvt) of
3614        {ok, {bound,_Usage,Ls}} ->
3615            {[],[{V,{bound,used,Ls}}],St};
3616        error ->
3617            case orddict:find(V, Vt) of
3618                {ok,{bound,_Usage,Ls}} ->
3619                    {[{V,{bound,used,Ls}}],[],St};
3620                {ok,{{unsafe,In},_Usage,Ls}} ->
3621                    {[{V,{bound,used,Ls}}],[],
3622                     add_error(Line, {unsafe_var,V,In}, St)};
3623                {ok,{{export,From},_Usage,Ls}} ->
3624                    {[{V,{bound,used,Ls}}],[],
3625                     %% As this is matching, exported vars are risky.
3626                     add_warning(Line, {exported_var,V,From}, St)};
3627                {ok,{stacktrace,_Usage,Ls}} ->
3628                    {[{V,{bound,used,Ls}}],[],
3629                     add_error(Line, {stacktrace_bound,V}, St)};
3630                error when St#lint.recdef_top ->
3631                    {[],[{V,{bound,unused,[Line]}}],
3632                     add_error(Line, {variable_in_record_def,V}, St)};
3633                error -> {[],[{V,{bound,unused,[Line]}}],St}
3634            end
3635    end.
3636
3637%% pat_binsize_var(Variable, LineNo, VarTable, BinVarTable, State) ->
3638%%      {UpdVarTable,UpdBinVarTable,State'}
3639%%  A pattern variable has been found. Handle errors and warnings. Return
3640%%  all variables as bound so errors and warnings are only reported once.
3641
3642pat_binsize_var(V, Line, Vt, Bvt, St) ->
3643    case orddict:find(V, Bvt) of
3644        {ok,{bound,_Used,Ls}} ->
3645            {[],[{V,{bound,used,Ls}}],St};
3646        error ->
3647            case orddict:find(V, Vt) of
3648                {ok,{bound,_Used,Ls}} ->
3649                    {[{V,{bound,used,Ls}}],[],St};
3650                {ok,{{unsafe,In},_Used,Ls}} ->
3651                    {[{V,{bound,used,Ls}}],[],
3652                     add_error(Line, {unsafe_var,V,In}, St)};
3653                {ok,{{export,From},_Used,Ls}} ->
3654                    {[{V,{bound,used,Ls}}],[],
3655                     %% As this is not matching, exported vars are
3656                     %% probably safe.
3657                     exported_var(Line, V, From, St)};
3658                error ->
3659                    {[{V,{bound,used,[Line]}}],[],
3660                     add_error(Line, {unbound_var,V}, St)}
3661            end
3662    end.
3663
3664%% expr_var(Variable, LineNo, VarTable, State) ->
3665%%      {UpdVarTable,State}
3666%%  Check if a variable is defined, or if there is an error or warning
3667%%  connected to its usage. Return all variables as bound so errors
3668%%  and warnings are only reported once.  As this is not matching
3669%%  exported vars are probably safe, warn only if warn_export_vars is
3670%%  set.
3671
3672expr_var(V, Line, Vt, #lint{bvt=none}=St) ->
3673    do_expr_var(V, Line, Vt, St);
3674expr_var(V, Line, Vt0, #lint{bvt=Bvt0}=St0) when is_list(Bvt0) ->
3675    {Vt,Bvt,St} = pat_binsize_var(V, Line, Vt0, Bvt0, St0),
3676    {Vt,St#lint{bvt=vtmerge(Bvt0, Bvt)}}.
3677
3678do_expr_var(V, Line, Vt, St) ->
3679    case orddict:find(V, Vt) of
3680        {ok,{bound,_Usage,Ls}} ->
3681            {[{V,{bound,used,Ls}}],St};
3682        {ok,{{unsafe,In},_Usage,Ls}} ->
3683            {[{V,{bound,used,Ls}}],
3684             add_error(Line, {unsafe_var,V,In}, St)};
3685        {ok,{{export,From},_Usage,Ls}} ->
3686            case is_warn_enabled(export_vars, St) of
3687                true ->
3688                    {[{V,{bound,used,Ls}}],
3689                     add_warning(Line, {exported_var,V,From}, St)};
3690                false ->
3691                    {[{V,{{export,From},used,Ls}}],St}
3692            end;
3693        {ok,{stacktrace,_Usage,Ls}} ->
3694            {[{V,{bound,used,Ls}}],
3695             add_error(Line, {stacktrace_guard,V}, St)};
3696        error ->
3697            {[{V,{bound,used,[Line]}}],
3698             add_error(Line, {unbound_var,V}, St)}
3699    end.
3700
3701exported_var(Line, V, From, St) ->
3702    case is_warn_enabled(export_vars, St) of
3703        true -> add_warning(Line, {exported_var,V,From}, St);
3704        false -> St
3705    end.
3706
3707shadow_vars(Vt, Vt0, In, St0) ->
3708    case is_warn_enabled(shadow_vars, St0) of
3709        true ->
3710            foldl(fun ({V,{_,_,[L | _]}}, St) ->
3711                          add_warning(L, {shadowed_var,V,In}, St);
3712                      (_, St) -> St
3713                  end, St0, vtold(Vt, vt_no_unsafe(Vt0)));
3714        false -> St0
3715    end.
3716
3717check_unused_vars(Vt, Vt0, St0) ->
3718    U = unused_vars(Vt, Vt0, St0),
3719    warn_unused_vars(U, Vt, St0).
3720
3721check_old_unused_vars(Vt, Vt0, St0) ->
3722    U = unused_vars(vtold(Vt, Vt0), [], St0),
3723    warn_unused_vars(U, Vt, St0).
3724
3725unused_vars(Vt, Vt0, _St0) ->
3726    U0 = orddict:filter(fun (V, {_State,unused,_Ls}) ->
3727                                case atom_to_list(V) of
3728                                    "_"++_ -> false;
3729                                    _ -> true
3730                                end;
3731                            (_V, _How) -> false
3732                        end, Vt),
3733    vtnew(U0, Vt0). % Only new variables.
3734
3735warn_unused_vars([], Vt, St0) ->
3736    {Vt,St0};
3737warn_unused_vars(U, Vt, St0) ->
3738    St1 = case is_warn_enabled(unused_vars, St0) of
3739	      false -> St0;
3740	      true ->
3741		  foldl(fun ({V,{_,unused,Ls}}, St) ->
3742				foldl(fun (L, St2) ->
3743					      add_warning(L, {unused_var,V},
3744							  St2)
3745				      end, St, Ls)
3746			end, St0, U)
3747	  end,
3748    %% Return all variables as bound so warnings are only reported once.
3749    UVt = map(fun ({V,{State,_,Ls}}) -> {V,{State,used,Ls}} end, U),
3750    {vtmerge(Vt, UVt), St1}.
3751
3752
3753is_var_bound(V, Vt) ->
3754    case orddict:find(V, Vt) of
3755        {ok,{bound,_Usage,_}} -> true;
3756        _ -> false
3757    end.
3758
3759
3760%% vtupdate(UpdVarTable, VarTable) -> VarTable.
3761%%  Add the variables in the updated vartable to VarTable. The variables
3762%%  will be updated with their property in UpdVarTable. The state of
3763%%  the variables in UpdVarTable will be returned.
3764
3765vtupdate(Uvt, Vt0) ->
3766    orddict:merge(fun (_V, {S,U1,L1}, {_S,U2,L2}) ->
3767                          {S, merge_used(U1, U2), merge_lines(L1, L2)}
3768                  end, Uvt, Vt0).
3769
3770%% vtunsafe(From, UpdVarTable, VarTable) -> UnsafeVarTable.
3771%%  Return all new variables in UpdVarTable as unsafe.
3772
3773vtunsafe({Tag,FileLine}, Uvt, Vt) ->
3774    Line = erl_anno:location(FileLine),
3775    [{V,{{unsafe,{Tag,Line}},U,Ls}} || {V,{_,U,Ls}} <- vtnew(Uvt, Vt)].
3776
3777%% vtmerge(VarTable, VarTable) -> VarTable.
3778%%  Merge two variables tables generating a new vartable. Give priority to
3779%%  errors then warnings.
3780
3781vtmerge(Vt1, Vt2) ->
3782    orddict:merge(fun (_V, {S1,U1,L1}, {S2,U2,L2}) ->
3783                          {merge_state(S1, S2),
3784                           merge_used(U1, U2),
3785                           merge_lines(L1, L2)}
3786                  end, Vt1, Vt2).
3787
3788vtmerge(Vts) -> foldl(fun (Vt, Mvts) -> vtmerge(Vt, Mvts) end, [], Vts).
3789
3790vtmerge_pat(Vt1, Vt2) ->
3791    orddict:merge(fun (_V, {S1,_Usage1,L1}, {S2,_Usage2,L2}) ->
3792                          {merge_state(S1, S2),used, merge_lines(L1, L2)}
3793                  end, Vt1, Vt2).
3794
3795merge_lines(Ls1, Ls2) ->
3796    ordsets:union(Ls1,Ls2).
3797
3798merge_state({unsafe,_F1}=S1, _S2) -> S1;          %Take the error case
3799merge_state(_S1, {unsafe,_F2}=S2) -> S2;
3800merge_state(bound, S2) -> S2;                   %Take the warning
3801merge_state(S1, bound) -> S1;
3802merge_state({export,F1},{export,_F2}) ->        %Sanity check
3803    %% We want to report the outermost construct
3804    {export,F1}.
3805
3806merge_used(used, _Usage2) -> used;
3807merge_used(_Usage1, used) -> used;
3808merge_used(unused, unused) -> unused.
3809
3810%% vtnew(NewVarTable, OldVarTable) -> NewVarTable.
3811%%  Return all the truly new variables in NewVarTable.
3812
3813vtnew(New, Old) ->
3814    orddict:filter(fun (V, _How) -> not orddict:is_key(V, Old) end, New).
3815
3816%% vtsubtract(VarTable1, VarTable2) -> NewVarTable.
3817%%  Return all the variables in VarTable1 which don't occur in VarTable2.
3818%%  Same thing as vtnew, but a more intuitive name for some uses.
3819vtsubtract(New, Old) ->
3820    vtnew(New, Old).
3821
3822%% vtold(NewVarTable, OldVarTable) -> OldVarTable.
3823%%  Return all the truly old variables in NewVarTable.
3824
3825vtold(New, Old) ->
3826    orddict:filter(fun (V, _How) -> orddict:is_key(V, Old) end, New).
3827
3828vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt,
3829                          case S of
3830                              {unsafe,_} -> false;
3831                              _ -> true
3832                          end].
3833
3834vt_no_unused(Vt) -> [V || {_,{_,U,_L}}=V <- Vt, U =/= unused].
3835
3836%% copy_expr(Expr, Line) -> Expr.
3837%%  Make a copy of Expr converting all line numbers to Line.
3838
3839copy_expr(Expr, Anno) ->
3840    erl_parse:map_anno(fun(_A) -> Anno end, Expr).
3841
3842%% Check a record_info call. We have already checked that it is not
3843%% shadowed by an import.
3844
3845check_record_info_call(_Line,La,[{atom,Li,Info},{atom,_Ln,Name}],St) ->
3846    case member(Info, [fields,size]) of
3847        true -> exist_record(La, Name, St);
3848        false -> add_error(Li, illegal_record_info, St)
3849    end;
3850check_record_info_call(Line,_La,_As,St) ->
3851    add_error(Line, illegal_record_info, St).
3852
3853has_wildcard_field([{record_field,_Lf,{var,_La,'_'},_Val}|_Fs]) -> true;
3854has_wildcard_field([_|Fs]) -> has_wildcard_field(Fs);
3855has_wildcard_field([]) -> false.
3856
3857%% check_remote_function(Line, ModuleName, FuncName, [Arg], State) -> State.
3858%%  Perform checks on known remote calls.
3859
3860check_remote_function(Line, M, F, As, St0) ->
3861    St1 = deprecated_function(Line, M, F, As, St0),
3862    St2 = check_qlc_hrl(Line, M, F, As, St1),
3863    St3 = check_load_nif(Line, M, F, As, St2),
3864    format_function(Line, M, F, As, St3).
3865
3866%% check_load_nif(Line, ModName, FuncName, [Arg], State) -> State
3867%%  Add warning if erlang:load_nif/2 is called when any kind of inlining has
3868%%  been enabled.
3869check_load_nif(Line, erlang, load_nif, [_, _], St) ->
3870    case is_warn_enabled(nif_inline, St) of
3871        true -> check_nif_inline(Line, St);
3872        false -> St
3873    end;
3874check_load_nif(_Line, _ModName, _FuncName, _Args, St) ->
3875    St.
3876
3877check_nif_inline(Line, St) ->
3878    case any(fun is_inline_opt/1, St#lint.compile) of
3879        true -> add_warning(Line, nif_inline, St);
3880        false -> St
3881    end.
3882
3883is_inline_opt({inline, [_|_]=_FAs}) -> true;
3884is_inline_opt(inline) -> true;
3885is_inline_opt(_) -> false.
3886
3887%% check_qlc_hrl(Line, ModName, FuncName, [Arg], State) -> State
3888%%  Add warning if qlc:q/1,2 has been called but qlc.hrl has not
3889%%  been included.
3890
3891check_qlc_hrl(Line, M, F, As, St) ->
3892    Arity = length(As),
3893    case As of
3894        [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q,
3895                                Arity < 3, not St#lint.xqlc ->
3896            add_warning(Line, {missing_qlc_hrl, Arity}, St);
3897        _ ->
3898            St
3899    end.
3900
3901%% deprecated_function(Line, ModName, FuncName, [Arg], State) -> State.
3902%%  Add warning for calls to deprecated functions.
3903
3904-dialyzer({no_match, deprecated_function/5}).
3905
3906deprecated_function(Line, M, F, As, St) ->
3907    Arity = length(As),
3908    MFA = {M, F, Arity},
3909    case otp_internal:obsolete(M, F, Arity) of
3910	{deprecated, String} when is_list(String) ->
3911            case not is_warn_enabled(deprecated_function, St) orelse
3912		ordsets:is_element(MFA, St#lint.not_deprecated) of
3913                true ->
3914		    St;
3915                false ->
3916		    add_warning(Line, {deprecated, MFA, String}, St)
3917            end;
3918	{deprecated, Replacement, Rel} ->
3919            case not is_warn_enabled(deprecated_function, St) orelse
3920		ordsets:is_element(MFA, St#lint.not_deprecated) of
3921                true ->
3922		    St;
3923                false ->
3924		    add_warning(Line, {deprecated, MFA, Replacement, Rel}, St)
3925            end;
3926	{removed, String} when is_list(String) ->
3927	    add_removed_warning(Line, MFA, {removed, MFA, String}, St);
3928	{removed, Replacement, Rel} ->
3929	    add_removed_warning(Line, MFA, {removed, MFA, Replacement, Rel}, St);
3930        no ->
3931	    St
3932    end.
3933
3934add_removed_warning(Line, {M, _, _}=MFA, Warning, #lint{not_removed=NotRemoved}=St) ->
3935    case is_warn_enabled(removed, St) andalso
3936        not gb_sets:is_element(M, NotRemoved) andalso
3937        not gb_sets:is_element(MFA, NotRemoved) of
3938        true ->
3939            add_warning(Line, Warning, St);
3940        false ->
3941            St
3942    end.
3943
3944-dialyzer({no_match, deprecated_type/5}).
3945
3946deprecated_type(L, M, N, As, St) ->
3947    NAs = length(As),
3948    case otp_internal:obsolete_type(M, N, NAs) of
3949        {deprecated, String} when is_list(String) ->
3950            case is_warn_enabled(deprecated_type, St) of
3951                true ->
3952                    add_warning(L, {deprecated_type, {M,N,NAs}, String}, St);
3953                false ->
3954                    St
3955            end;
3956        {removed, String} ->
3957            add_warning(L, {removed_type, {M,N,NAs}, String}, St);
3958        no ->
3959            St
3960    end.
3961
3962obsolete_guard({call,Line,{atom,Lr,F},As}, St0) ->
3963    Arity = length(As),
3964    case erl_internal:old_type_test(F, Arity) of
3965	false ->
3966	    deprecated_function(Line, erlang, F, As, St0);
3967	true ->
3968	    St = case is_warn_enabled(obsolete_guard, St0) of
3969		     true ->
3970			 add_warning(Lr, {obsolete_guard, {F, Arity}}, St0);
3971		     false ->
3972			 St0
3973		 end,
3974	    test_overriden_by_local(Lr, F, Arity, St)
3975    end;
3976obsolete_guard(_G, St) ->
3977    St.
3978
3979test_overriden_by_local(Line, OldTest, Arity, St) ->
3980    ModernTest = list_to_atom("is_"++atom_to_list(OldTest)),
3981    case is_local_function(St#lint.locals, {ModernTest, Arity}) of
3982	true ->
3983	    add_error(Line, {obsolete_guard_overridden,OldTest}, St);
3984	false ->
3985	    St
3986    end.
3987
3988%% keyword_warning(Line, Atom, State) -> State.
3989%%  Add warning for atoms that will be reserved keywords in the future.
3990%%  (Currently, no such keywords to warn for.)
3991keyword_warning(_Line, _A, St) -> St.
3992
3993%% format_function(Line, ModName, FuncName, [Arg], State) -> State.
3994%%  Add warning for bad calls to io:fwrite/format functions.
3995
3996format_function(Line, M, F, As, St) ->
3997    case is_format_function(M, F) of
3998        true ->
3999            case St#lint.warn_format of
4000                Lev when Lev > 0 ->
4001                    case check_format_1(As) of
4002                        {warn,Level,Fmt,Fas} when Level =< Lev ->
4003                            add_warning(Line, {format_error,{Fmt,Fas}}, St);
4004                        _ -> St
4005                    end;
4006                _Lev -> St
4007            end;
4008        false -> St
4009    end.
4010
4011is_format_function(io, fwrite) -> true;
4012is_format_function(io, format) -> true;
4013is_format_function(io_lib, fwrite) -> true;
4014is_format_function(io_lib, format) -> true;
4015is_format_function(M, F) when is_atom(M), is_atom(F) -> false.
4016
4017%% check_format_1([Arg]) -> ok | {warn,Level,Format,[Arg]}.
4018
4019check_format_1([Fmt]) ->
4020    check_format_1([Fmt,{nil,0}]);
4021check_format_1([Fmt,As]) ->
4022    check_format_2(Fmt, canonicalize_string(As));
4023check_format_1([_Dev,Fmt,As]) ->
4024    check_format_1([Fmt,As]);
4025check_format_1(_As) ->
4026    {warn,1,"format call with wrong number of arguments",[]}.
4027
4028canonicalize_string({string,Line,Cs}) ->
4029    foldr(fun (C, T) -> {cons,Line,{integer,Line,C},T} end, {nil,Line}, Cs);
4030canonicalize_string(Term) ->
4031    Term.
4032
4033%% check_format_2([Arg]) -> ok | {warn,Level,Format,[Arg]}.
4034
4035check_format_2(Fmt, As) ->
4036    case Fmt of
4037        {string,_L,S} -> check_format_2a(S, As);
4038        {atom,_L,A} -> check_format_2a(atom_to_list(A), As);
4039        _ -> {warn,2,"format string not a textual constant",[]}
4040    end.
4041
4042check_format_2a(Fmt, As) ->
4043    case args_list(As) of
4044        true -> check_format_3(Fmt, As);
4045        false -> {warn,1,"format arguments not a list",[]};
4046        maybe -> {warn,2,"format arguments perhaps not a list",[]}
4047    end.
4048
4049%% check_format_3(FormatString, [Arg]) -> ok | {warn,Level,Format,[Arg]}.
4050
4051check_format_3(Fmt, As) ->
4052    case check_format_string(Fmt) of
4053        {ok,Need} ->
4054            case args_length(As) of
4055                Len when length(Need) =:= Len -> ok;
4056                _Len -> {warn,1,"wrong number of arguments in format call",[]}
4057            end;
4058        {error,S} ->
4059            {warn,1,"format string invalid (~ts)",[S]}
4060    end.
4061
4062args_list({cons,_L,_H,T}) -> args_list(T);
4063%% Strange case: user has written something like [a | "bcd"]; pretend
4064%% we don't know:
4065args_list({string,_L,_Cs}) -> maybe;
4066args_list({nil,_L}) -> true;
4067args_list({atom,_,_}) -> false;
4068args_list({integer,_,_}) -> false;
4069args_list({float,_,_}) -> false;
4070args_list(_Other) -> maybe.
4071
4072args_length({cons,_L,_H,T}) -> 1 + args_length(T);
4073args_length({nil,_L}) -> 0.
4074
4075check_format_string(Fmt) ->
4076    extract_sequences(Fmt, []).
4077
4078extract_sequences(Fmt, Need0) ->
4079    case string:find(Fmt, [$~]) of
4080        nomatch -> {ok,lists:reverse(Need0)};         %That's it
4081        [$~|Fmt1] ->
4082            case extract_sequence(1, Fmt1, Need0) of
4083                {ok,Need1,Rest} -> extract_sequences(Rest, Need1);
4084                Error -> Error
4085            end
4086    end.
4087
4088extract_sequence(1, [$-,C|Fmt], Need) when C >= $0, C =< $9 ->
4089    extract_sequence_digits(1, Fmt, Need);
4090extract_sequence(1, [C|Fmt], Need) when C >= $0, C =< $9 ->
4091    extract_sequence_digits(1, Fmt, Need);
4092extract_sequence(1, [$-,$*|Fmt], Need) ->
4093    extract_sequence(2, Fmt, [int|Need]);
4094extract_sequence(1, [$*|Fmt], Need) ->
4095    extract_sequence(2, Fmt, [int|Need]);
4096extract_sequence(1, Fmt, Need) ->
4097    extract_sequence(2, Fmt, Need);
4098extract_sequence(2, [$.,C|Fmt], Need) when C >= $0, C =< $9 ->
4099    extract_sequence_digits(2, Fmt, Need);
4100extract_sequence(2, [$.,$*|Fmt], Need) ->
4101    extract_sequence(3, Fmt, [int|Need]);
4102extract_sequence(2, [$.|Fmt], Need) ->
4103    extract_sequence(3, Fmt, Need);
4104extract_sequence(2, Fmt, Need) ->
4105    extract_sequence(4, Fmt, Need);
4106extract_sequence(3, [$.,$*|Fmt], Need) ->
4107    extract_sequence(4, Fmt, [int|Need]);
4108extract_sequence(3, [$.,_|Fmt], Need) ->
4109    extract_sequence(4, Fmt, Need);
4110extract_sequence(3, Fmt, Need) ->
4111    extract_sequence(4, Fmt, Need);
4112extract_sequence(4, [$t, $l | Fmt], Need) ->
4113    extract_sequence(4, [$l, $t | Fmt], Need);
4114extract_sequence(4, [$t, $c | Fmt], Need) ->
4115    extract_sequence(5, [$c|Fmt], Need);
4116extract_sequence(4, [$t, $s | Fmt], Need) ->
4117    extract_sequence(5, [$s|Fmt], Need);
4118extract_sequence(4, [$t, $p | Fmt], Need) ->
4119    extract_sequence(5, [$p|Fmt], Need);
4120extract_sequence(4, [$t, $P | Fmt], Need) ->
4121    extract_sequence(5, [$P|Fmt], Need);
4122extract_sequence(4, [$t, $w | Fmt], Need) ->
4123    extract_sequence(5, [$w|Fmt], Need);
4124extract_sequence(4, [$t, $W | Fmt], Need) ->
4125    extract_sequence(5, [$W|Fmt], Need);
4126extract_sequence(4, [$t, C | _Fmt], _Need) ->
4127    {error,"invalid control ~t" ++ [C]};
4128extract_sequence(4, [$l, $p | Fmt], Need) ->
4129    extract_sequence(5, [$p|Fmt], Need);
4130extract_sequence(4, [$l, $t, $p | Fmt], Need) ->
4131    extract_sequence(5, [$p|Fmt], Need);
4132extract_sequence(4, [$l, $P | Fmt], Need) ->
4133    extract_sequence(5, [$P|Fmt], Need);
4134extract_sequence(4, [$l, $t, $P | Fmt], Need) ->
4135    extract_sequence(5, [$P|Fmt], Need);
4136extract_sequence(4, [$l, $t, C | _Fmt], _Need) ->
4137    {error,"invalid control ~lt" ++ [C]};
4138extract_sequence(4, [$l, C | _Fmt], _Need) ->
4139    {error,"invalid control ~l" ++ [C]};
4140extract_sequence(4, Fmt, Need) ->
4141    extract_sequence(5, Fmt, Need);
4142extract_sequence(5, [C|Fmt], Need0) ->
4143    case control_type(C, Need0) of
4144        error -> {error,"invalid control ~" ++ [C]};
4145        Need1 -> {ok,Need1,Fmt}
4146    end;
4147extract_sequence(_, [], _Need) -> {error,"truncated"}.
4148
4149extract_sequence_digits(Fld, [C|Fmt], Need) when C >= $0, C =< $9 ->
4150    extract_sequence_digits(Fld, Fmt, Need);
4151extract_sequence_digits(Fld, Fmt, Need) ->
4152    extract_sequence(Fld+1, Fmt, Need).
4153
4154control_type($~, Need) -> Need;
4155control_type($c, Need) -> [int|Need];
4156control_type($f, Need) -> [float|Need];
4157control_type($e, Need) -> [float|Need];
4158control_type($g, Need) -> [float|Need];
4159control_type($s, Need) -> [string|Need];
4160control_type($w, Need) -> [term|Need];
4161control_type($p, Need) -> [term|Need];
4162control_type($W, Need) -> [int,term|Need]; %% Note: reversed
4163control_type($P, Need) -> [int,term|Need]; %% Note: reversed
4164control_type($b, Need) -> [term|Need];
4165control_type($B, Need) -> [term|Need];
4166control_type($x, Need) -> [string,term|Need]; %% Note: reversed
4167control_type($X, Need) -> [string,term|Need]; %% Note: reversed
4168control_type($+, Need) -> [term|Need];
4169control_type($#, Need) -> [term|Need];
4170control_type($n, Need) -> Need;
4171control_type($i, Need) -> [term|Need];
4172control_type(_C, _Need) -> error.
4173
4174
4175%% Prebuild set of local functions (to override auto-import)
4176local_functions(Forms) ->
4177    gb_sets:from_list([ {Func,Arity} || {function,_,Func,Arity,_} <- Forms ]).
4178%% Predicate to find out if the function is locally defined
4179is_local_function(LocalSet,{Func,Arity}) ->
4180    gb_sets:is_element({Func,Arity},LocalSet).
4181%% Predicate to see if a function is explicitly imported
4182is_imported_function(ImportSet,{Func,Arity}) ->
4183    case orddict:find({Func,Arity}, ImportSet) of
4184        {ok,_Mod} -> true;
4185        error -> false
4186    end.
4187%% Predicate to see if a function is explicitly imported from the erlang module
4188is_imported_from_erlang(ImportSet,{Func,Arity}) ->
4189    case orddict:find({Func,Arity}, ImportSet) of
4190        {ok,erlang} -> true;
4191        _ -> false
4192    end.
4193%% Build set of functions where auto-import is explicitly suppressed
4194auto_import_suppressed(CompileFlags) ->
4195    case lists:member(no_auto_import, CompileFlags) of
4196        true ->
4197            all;
4198        false ->
4199            L0 = [ X || {no_auto_import,X} <- CompileFlags ],
4200            L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ],
4201            gb_sets:from_list(L1)
4202    end.
4203%% Predicate to find out if autoimport is explicitly suppressed for a function
4204is_autoimport_suppressed(all,{_Func,_Arity}) ->
4205    true;
4206is_autoimport_suppressed(NoAutoSet,{Func,Arity}) ->
4207    gb_sets:is_element({Func,Arity},NoAutoSet).
4208%% Predicate to find out if a function specific bif-clash suppression (old deprecated) is present
4209bif_clash_specifically_disabled(St,{F,A}) ->
4210    lists:member({F,A},St#lint.nowarn_bif_clash).
4211
4212%% Predicate to find out if an autoimported guard_bif is not overriden in some way
4213%% Guard Bif without module name is disallowed if
4214%% * It is overridden by local function
4215%% * It is overridden by -import and that import is not of itself (i.e. from module erlang)
4216%% * The autoimport is suppressed or it's not reimported by -import directive
4217%% Otherwise it's OK (given that it's actually a guard bif and actually is autoimported)
4218no_guard_bif_clash(St,{F,A}) ->
4219    (
4220      (not is_local_function(St#lint.locals,{F,A}))
4221      andalso
4222      (
4223        (not is_imported_function(St#lint.imports,{F,A})) orelse
4224	 is_imported_from_erlang(St#lint.imports,{F,A})
4225      )
4226      andalso
4227      (
4228        (not is_autoimport_suppressed(St#lint.no_auto, {F,A})) orelse
4229	 is_imported_from_erlang(St#lint.imports,{F,A})
4230      )
4231    ).
4232
4233%% maps_prepend(Key, Value, Map) -> Map.
4234
4235maps_prepend(Key, Value, Map) ->
4236    case maps:find(Key, Map) of
4237        {ok, Values} ->
4238            maps:put(Key, [Value|Values], Map);
4239        error ->
4240            maps:put(Key, [Value], Map)
4241    end.
4242