1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 1999-2013. All Rights Reserved.
    5: %%
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %%
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %%
   17: %% %CopyrightEnd%
   18: %%
   19: -module(erl_lint_SUITE).
   20: 
   21: %-define(debug, true).
   22: 
   23: -ifdef(debug).
   24: -define(line, put(line, ?LINE), ).
   25: -define(config(X,Y), foo).
   26: -define(datadir, "erl_lint_SUITE_data").
   27: -define(privdir, "erl_lint_SUITE_priv").
   28: -define(t, test_server).
   29: -else.
   30: -include_lib("test_server/include/test_server.hrl").
   31: -define(datadir, ?config(data_dir, Conf)).
   32: -define(privdir, ?config(priv_dir, Conf)).
   33: -endif.
   34: 
   35: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   36: 	 init_per_group/2,end_per_group/2, 
   37: 	 init_per_testcase/2, end_per_testcase/2]).
   38: 
   39: -export([ 
   40: 	  unused_vars_warn_basic/1, 
   41: 	  unused_vars_warn_lc/1, 
   42: 	  unused_vars_warn_rec/1,
   43: 	  unused_vars_warn_fun/1, 
   44: 	  unused_vars_OTP_4858/1,
   45: 	  export_vars_warn/1,
   46: 	  shadow_vars/1,
   47: 	  unused_import/1,
   48: 	  unused_function/1,
   49: 	  unsafe_vars/1,unsafe_vars2/1,
   50: 	  unsafe_vars_try/1,
   51: 	  guard/1, otp_4886/1, otp_4988/1, otp_5091/1, otp_5276/1, otp_5338/1,
   52: 	  otp_5362/1, otp_5371/1, otp_7227/1, otp_5494/1, otp_5644/1, otp_5878/1,
   53: 	  otp_5917/1, otp_6585/1, otp_6885/1, otp_10436/1, otp_11254/1,
   54:           export_all/1,
   55: 	  bif_clash/1,
   56: 	  behaviour_basic/1, behaviour_multiple/1,
   57: 	  otp_7550/1,
   58: 	  otp_8051/1,
   59: 	  format_warn/1,
   60: 	  on_load_successful/1, on_load_failing/1, 
   61: 	  too_many_arguments/1,
   62: 	  basic_errors/1,bin_syntax_errors/1
   63:         ]).
   64: 
   65: % Default timetrap timeout (set in init_per_testcase).
   66: -define(default_timeout, ?t:minutes(1)).
   67: 
   68: init_per_testcase(_Case, Config) ->
   69:     ?line Dog = ?t:timetrap(?default_timeout),
   70:     [{watchdog, Dog} | Config].
   71: 
   72: end_per_testcase(_Case, _Config) ->
   73:     Dog = ?config(watchdog, _Config),
   74:     test_server:timetrap_cancel(Dog),
   75:     ok.
   76: 
   77: suite() -> [{ct_hooks,[ts_install_cth]}].
   78: 
   79: all() -> 
   80:     [{group, unused_vars_warn}, export_vars_warn,
   81:      shadow_vars, unused_import, unused_function,
   82:      unsafe_vars, unsafe_vars2, unsafe_vars_try, guard,
   83:      otp_4886, otp_4988, otp_5091, otp_5276, otp_5338,
   84:      otp_5362, otp_5371, otp_7227, otp_5494, otp_5644,
   85:      otp_5878, otp_5917, otp_6585, otp_6885, otp_10436, otp_11254,export_all,
   86:      bif_clash, behaviour_basic, behaviour_multiple,
   87:      otp_7550, otp_8051, format_warn, {group, on_load},
   88:      too_many_arguments, basic_errors, bin_syntax_errors].
   89: 
   90: groups() -> 
   91:     [{unused_vars_warn, [],
   92:       [unused_vars_warn_basic, unused_vars_warn_lc,
   93:        unused_vars_warn_rec, unused_vars_warn_fun,
   94:        unused_vars_OTP_4858]},
   95:      {on_load, [], [on_load_successful, on_load_failing]}].
   96: 
   97: init_per_suite(Config) ->
   98:     Config.
   99: 
  100: end_per_suite(_Config) ->
  101:     ok.
  102: 
  103: init_per_group(_GroupName, Config) ->
  104:     Config.
  105: 
  106: end_per_group(_GroupName, Config) ->
  107:     Config.
  108: 
  109: 
  110: 
  111: unused_vars_warn_basic(doc) ->
  112:     "Warnings for unused variables in some simple cases.";
  113: unused_vars_warn_basic(suite) -> [];
  114: unused_vars_warn_basic(Config) when is_list(Config) ->
  115:     Ts = [{basic1,
  116:            <<"f(F) -> % F unused.
  117:                 ok.
  118: 
  119:             f(F, F) ->
  120:                 ok.
  121: 
  122:             g(_X) ->
  123:                 y.
  124: 
  125:             h(P) ->
  126:                 P.
  127: 
  128:             x(N) ->
  129:                 case a:b() of
  130:                     [N|Y] -> % Y unused.
  131:                         ok
  132:                 end.
  133: 
  134:             y(N, L) ->
  135:                 lists:map(fun(T) -> T*N end, L).
  136: 
  137:             z(N, L) -> % N unused
  138:                 lists:map(fun(N, T) -> T*N end, L).  % N shadowed.
  139: 
  140: 
  141:             c(A) ->
  142:                 case A of
  143:                     1 -> B = []; % B unused.
  144:                     2 -> B = []; % B unused.
  145:                     3 -> B = f, B
  146:                 end.
  147:            ">>,
  148: 	   [warn_unused_vars],
  149: 	   {warnings,[{1,erl_lint,{unused_var,'F'}},
  150:              {15,erl_lint,{unused_var,'Y'}},
  151:              {22,erl_lint,{unused_var,'N'}},
  152:              {23,erl_lint,{shadowed_var,'N','fun'}},
  153:              {28,erl_lint,{unused_var,'B'}},
  154:              {29,erl_lint,{unused_var,'B'}}]}},
  155:           {basic2,
  156:            <<"-record(r, {x,y}).
  157:               f({X,Y}) -> {Z=X,Z=Y};
  158:               f([H|T]) -> [Z=H|Z=T];
  159:               f(#r{x=X,y=Y}) -> #r{x=A=X,y=A=Y}.
  160:               g({M, F}) -> (Z=M):(Z=F)();
  161:               g({M, F, Arg}) -> (Z=M):F(Z=Arg).
  162:               h(X, Y) -> (Z=X) + (Z=Y).">>,
  163:            [warn_unused_vars], []}],
  164:     ?line [] = run(Config, Ts),
  165:     ok.
  166: 
  167: unused_vars_warn_lc(doc) ->
  168:     "Warnings for unused variables in list comprehensions.";
  169: unused_vars_warn_lc(suite) -> [];
  170: unused_vars_warn_lc(Config) when is_list(Config) ->
  171:     Ts = [{lc1, 
  172:            <<"bin([X]) ->
  173:                   [A || <<A:X>> <- []]; % X used, not shadowed.
  174:               bin({X}) ->
  175:                   [X || <<X:X>> <- []]; % X used, and shadowed.
  176:               bin({X,Y,Z}) ->
  177:                   [{A,B} || <<A:X>> <- Z, <<B:Y>> <- Z];
  178:               bin([X,Y,Z]) -> % Y unused.
  179:                   [C || <<V:X>> <- Z, <<B:V>> <- Z, <<C:B>> <- Z].
  180:            ">>, 
  181:            [warn_unused_vars],
  182:            {warnings, [{4,erl_lint,{shadowed_var,'X',generate}},
  183:                        {7,erl_lint,{unused_var,'Y'}}]}},
  184: 
  185:           {lc2,
  186:            <<"bin([X]) ->
  187:                   [A || <<A:X>> <- []]; % X used, not shadowed.
  188:               bin({X}) ->
  189:                   [X || <<X:X>> <- []]; % X used, and shadowed.
  190:               bin({X,Y,Z}) ->
  191:                   [{A,B} || <<A:X>> <- Z, <<B:Y>> <- Z];
  192:               bin([X,Y,Z]) -> % Y unused.
  193:                   [C || <<V:X>> <- Z, <<B:V>> <- Z, <<C:B>> <- Z].
  194:            ">>,
  195:            [warn_unused_vars],
  196:            {warnings,[{4,erl_lint,{shadowed_var,'X',generate}},
  197:                       {7,erl_lint,{unused_var,'Y'}}]}},
  198: 
  199:           {lc3,
  200:            <<"a([A]) ->
  201:                   B = foo,
  202:                   [{C,B} || {C,_} <- A];
  203:               a({A}) ->
  204:                   B = foo,
  205:                   [C || {C,_} <- [B,A]];
  206:               a({A,A}) ->
  207:                   B = foo,
  208:                   [C || {C,_} <- B, B < A].
  209:            ">>,
  210:            [warn_unused_vars],
  211:            []},
  212: 
  213:           {lc4,
  214:            <<"b(A) ->
  215:                   B = foo, % B unused.
  216:                   [C || {C,_} <- A].
  217:            ">>,
  218:            [warn_unused_vars],
  219:            {warnings,[{2,erl_lint,{unused_var,'B'}}]}},
  220: 
  221:           {lc5,
  222:            <<"c(A) ->
  223:                   B = foo,
  224:                   [C || {C,_} <- A],
  225:                   B.
  226:            ">>,
  227:            [warn_unused_vars],
  228:            []},
  229: 
  230:           {lc6,
  231:            <<"d(A) ->
  232:                   B = foo,
  233:                   [{A,B} || {Id,_} <- A]. % Id unused.
  234:            ">>,
  235:            [warn_unused_vars],
  236:            {warnings,[{3,erl_lint,{unused_var,'Id'}}]}},
  237: 
  238:           {lc7,
  239:            <<"e(A) ->
  240:                   B = foo, % B unused.
  241:                   [B || B <- A]. % B shadowed.
  242:            ">>,
  243:            [warn_unused_vars],
  244:            {warnings,[{2,erl_lint,{unused_var,'B'}},
  245:                       {3,erl_lint,{shadowed_var,'B',generate}}]}},
  246: 
  247:           {lc8,
  248:            <<"f(A) ->
  249:                   B = foo,
  250:                   [B || B <- A], % B shadowed.
  251:                   B.
  252:            ">>,
  253:            [warn_unused_vars],
  254:            {warnings,[{3,erl_lint,{shadowed_var,'B',generate}}]}},
  255: 
  256:           {lc9,
  257:            <<"g(A) ->
  258:                   B = foo, % B unused.
  259:                   [A || B <- A]. % B shadowed, B unused.
  260:            ">>,
  261:            [warn_unused_vars],
  262:            {warnings,[{2,erl_lint,{unused_var,'B'}},
  263:                       {3,erl_lint,{unused_var,'B'}},
  264:                       {3,erl_lint,{shadowed_var,'B',generate}}]}},
  265: 
  266:           {lc10,
  267:            <<"h(A) ->
  268:                   B = foo,
  269:                   [A || B <- A], % B shadowed, B unused.
  270:                   B.
  271:            ">>,
  272:            [warn_unused_vars],
  273:            {warnings,[{3,erl_lint,{unused_var,'B'}},
  274:                       {3,erl_lint,{shadowed_var,'B',generate}}]}},
  275: 
  276:           {lc11,
  277:            <<"i(X) ->
  278:                   [Z || Z <- X, % Z unused.
  279:                         Z = X <- [foo]]. % X and Z shadowed. X unused!
  280:            ">>,
  281:            [warn_unused_vars],
  282:            {warnings,[{2,erl_lint,{unused_var,'Z'}},
  283:                       {3,erl_lint,{unused_var,'X'}},
  284:                       {3,erl_lint,{shadowed_var,'X',generate}},
  285:                       {3,erl_lint,{shadowed_var,'Z',generate}}]}},
  286: 
  287:           {lc12,
  288:            <<"j({X}) ->
  289:                   [Z || Z <- X, % Z unused.
  290:                         Z <- X = [[1,2,3]], % Z shadowed. Z unused.
  291:                         Z <- X, % Z shadowed. Z unused.
  292:                         Z <- X]; % Z shadowed.
  293:               j(X) ->
  294:                   [foo || X <- X, % X shadowed.
  295:                         X <-    % X shadowed. X unused.
  296:                              X = 
  297:                                  Y = [[1,2,3]], % Y unused.
  298:                         X <- [], % X shadowed.
  299:                         X <- X]. % X shadowed. X unused.
  300:            ">>,
  301:            [warn_unused_vars],
  302:            {warnings,[{2,erl_lint,{unused_var,'Z'}},
  303:                       {3,erl_lint,{unused_var,'Z'}},
  304:                       {3,erl_lint,{shadowed_var,'Z',generate}},
  305:                       {4,erl_lint,{unused_var,'Z'}},
  306:                       {4,erl_lint,{shadowed_var,'Z',generate}},
  307:                       {5,erl_lint,{shadowed_var,'Z',generate}},
  308:                       {7,erl_lint,{shadowed_var,'X',generate}},
  309:                       {8,erl_lint,{unused_var,'X'}},
  310:                       {8,erl_lint,{shadowed_var,'X',generate}},
  311:                       {10,erl_lint,{unused_var,'Y'}},
  312:                       {11,erl_lint,{shadowed_var,'X',generate}},
  313:                       {12,erl_lint,{unused_var,'X'}},
  314:                       {12,erl_lint,{shadowed_var,'X',generate}}]}},
  315: 
  316:           {lc13,
  317:            <<"k(X) ->
  318:                   [Z || Z <- Y = X]; % Y unused.
  319:               k(X) ->
  320:                   [Z || Z <- X = Y = X]; % Y unused!
  321:               k(X) ->
  322:                   [Z || Z <- begin X = Y = X, Y end];
  323:               k(X) ->
  324:                   [{Y,W} || W <- Y = X]; % Y unbound
  325:               k(X) ->
  326:                   [Z || Z <- (Y = X), % Y unused.
  327:                        Y > X]; % Y unbound.
  328:               k(X) ->
  329:                   [Y || Y = X > 3, Z = X]; % Z unused.
  330:               k(X) ->
  331:                   [Z || Y = X > 3, Z = X]. % Y unused.
  332:            ">>,
  333:            [warn_unused_vars],
  334:            {error,[{8,erl_lint,{unbound_var,'Y'}},
  335:                    {11,erl_lint,{unbound_var,'Y'}}],
  336:                   [{2,erl_lint,{unused_var,'Y'}},
  337:                    {4,erl_lint,{unused_var,'Y'}},
  338:                    {8,erl_lint,{unused_var,'Y'}},
  339:                    {10,erl_lint,{unused_var,'Y'}},
  340:                    {13,erl_lint,{unused_var,'Z'}},
  341:                    {15,erl_lint,{unused_var,'Y'}}]}},
  342: 
  343:           {lc14,
  344:            <<"lc2() ->
  345:                   Z = [[1],[2],[3]], 
  346:                   [X || Z <- Z, % Z shadowed.
  347:                         X <- Z].
  348:            ">>,
  349:            [warn_unused_vars],
  350:            {warnings,[{3,erl_lint,{shadowed_var,'Z',generate}}]}},
  351: 
  352:           {lc15,
  353:            <<"lc3() ->
  354:                   Z = [1,2,3], 
  355:                   [X || X <- Z, 
  356:                         Z <- Z]. % Z shadowed. Z unused.
  357:            ">>,
  358:            [warn_unused_vars],
  359:            {warnings,[{4,erl_lint,{unused_var,'Z'}},
  360:                       {4,erl_lint,{shadowed_var,'Z',generate}}]}},
  361: 
  362:           {lc16,
  363:            <<"bin(Z) ->
  364:                   case bar of
  365:                       true ->
  366:                           U = 2;
  367:                       false ->
  368:                           true
  369:                   end,
  370:                   case bar of
  371:                       true ->
  372:                           X = 2;
  373:                       false ->
  374:                           X = 3
  375:                   end,
  376:                   case foo of
  377:                       true ->
  378:                           Y = 3; % Y unused.
  379:                       false ->
  380:                           4
  381:                   end,
  382:                   case foo of
  383:                       1 ->
  384:                           U; % U unsafe.
  385:                       2 ->
  386:                           [Z || <<U:X>> <- Z]; % (X exported.) U unused.
  387:                       3 ->
  388:                           [Z || <<U:X>> <- Z], % (X exported.) U unused.
  389:                           U % U unsafe.
  390:                   end.
  391:            ">>,
  392:            [warn_unused_vars],
  393:            {error,[{22,erl_lint,{unsafe_var,'U',{'case',2}}},
  394:                    {27,erl_lint,{unsafe_var,'U',{'case',2}}}],
  395:             [{16,erl_lint,{unused_var,'Y'}},
  396:      %  {24,erl_lint,{exported_var,'X',{'case',8}}},
  397:              {24,erl_lint,{unused_var,'U'}},
  398:      %  {26,erl_lint,{exported_var,'X',{'case',8}}},
  399:              {26,erl_lint,{unused_var,'U'}}]}},
  400: 
  401:           {lc17,
  402:            <<"bin(Z) ->
  403:                   %% This used to pass erl_lint...
  404:                   case bar of
  405:                       true ->
  406:                           U = 2;
  407:                       false ->
  408:                           true
  409:                   end,
  410:                   case bar of
  411:                       true ->
  412:                           X = 2;
  413:                       false ->
  414:                           X = 3
  415:                   end,
  416:                   case foo of
  417:                       true ->
  418:                           Y = 3; % Y unused.
  419:                       false ->
  420:                           4
  421:                   end,
  422:                   [Z || <<U:X>> <- Z], % (X exported.) U unused.
  423:                   U. % U unsafe.
  424:            ">>,
  425:            [warn_unused_vars],
  426:            {error,[{22,erl_lint,{unsafe_var,'U',{'case',3}}}],
  427:             [{17,erl_lint,{unused_var,'Y'}},
  428:      %  {21,erl_lint,{exported_var,'X',{'case',9}}},
  429:              {21,erl_lint,{unused_var,'U'}}]}},
  430: 
  431:           {lc18,
  432:            <<"bin(Z) ->
  433:                   case bar of
  434:                       true ->
  435:                           U = 2;
  436:                       false ->
  437:                           true
  438:                   end,
  439:                   case bar of
  440:                       true ->
  441:                           X = 2;
  442:                       false ->
  443:                           X = 3
  444:                   end,
  445:                   case foo of
  446:                       true ->
  447:                           Y = 3;
  448:                       false ->
  449:                           4
  450:                   end,
  451:                   [B || <<U: % U unused
  452:                           U>> <- X, <<B:Y>> <- Z]. % U unsafe. Y unsafe. 
  453:                                                    % U shadowed. (X exported.)
  454:            ">>,
  455:            [warn_unused_vars],
  456:            {error,[{21,erl_lint,{unsafe_var,'U',{'case',2}}},
  457:                    {21,erl_lint,{unsafe_var,'Y',{'case',14}}}],
  458:             [{20,erl_lint,{unused_var,'U'}}
  459:      %       ,{21,erl_lint,{exported_var,'X',{'case',8}}}
  460:      %       ,{21,erl_lint,{shadowed_var,'U',generate}}
  461:             ]}},
  462: 
  463:           {lc19,
  464:            <<"p({B,C}) ->
  465:                   <<A:B,A:C>> = <<17:32>>;
  466:               p(B) ->
  467:                   <<A:B>> = <<17:32>>. % A unused.
  468:            ">>,
  469:            [warn_unused_vars],
  470:            {warnings,[{4,erl_lint,{unused_var,'A'}}]}},
  471: 
  472:           {lc20,
  473:            <<"c({I1,I2}) ->
  474:                   if
  475:                       <<I1:I2>> == <<>> ->
  476:                           foo
  477:                   end;
  478:               c([C1,C2]) -> % C1 unused.
  479:                   case foo of
  480:                       <<C2:C2,
  481:                         C3:C2>> -> % C3 unused.
  482:                           bar
  483:                   end.
  484: 
  485:            ">>,
  486:            [warn_unused_vars],
  487:            {warnings,[{6,erl_lint,{unused_var,'C1'}},
  488: 		      {7,sys_core_fold,no_clause_match},
  489:                       {9,erl_lint,{unused_var,'C3'}}]}},
  490: 
  491:           {lc21,
  492:            <<"t() ->
  493:                   S = 8,
  494:                   case <<3:8>> of
  495:                       <<X:S>> ->
  496:                           X;
  497:                       <<S:X>> -> % X unbound
  498:                           foo
  499:                   end;
  500:               t() ->
  501:                   S = 8,
  502:                   case <<3:8>> of
  503:                       <<S:S>> ->
  504:                           S;
  505:                       <<Q:32>> -> % Q unused.
  506:                           foo
  507:                   end.
  508:            ">>,
  509:            [warn_unused_vars],
  510:            {error,[{6,erl_lint,{unbound_var,'X'}}],
  511:                   [{14,erl_lint,{unused_var,'Q'}}]}}
  512: 
  513:           ],
  514:     ?line [] = run(Config, Ts),
  515:     ok.
  516: 
  517: 
  518: unused_vars_warn_rec(doc) ->
  519:     "Warnings for unused variables in records.";
  520: unused_vars_warn_rec(suite) -> [];
  521: unused_vars_warn_rec(Config) when is_list(Config) ->
  522:     Ts = [{rec1, % An example provided by Bjorn.
  523:            <<"-record(edge,
  524:                       {ltpr,
  525:                        ltsu,
  526:                        rtpr,
  527:                        rtsu
  528:                       }).
  529: 
  530:               f1(#edge{ltpr = A, ltsu = A}) ->
  531:                   true;
  532:               f1({Q, Q}) ->
  533:                   true.
  534: 
  535:               f2(Edge, Etab) ->
  536:                   case gb_trees:lookup(Edge, Etab) of
  537:                       {value,#edge{ltpr=Same,ltsu=Same}} -> ok;
  538:                       {value,_} -> error
  539:                   end.
  540: 
  541:               bar(Edge, Etab) ->
  542:                   case gb_trees:lookup(Edge, Etab) of
  543:                       {Same,Same} -> ok;
  544:                       {value,#edge{ltpr=Same}} -> ok; % Same unused.
  545:                       {value,_} -> error
  546:                   end.
  547:            ">>,
  548:            [warn_unused_vars],
  549:            {warnings,[{22,erl_lint,{unused_var,'Same'}}]}},
  550:           {rec2,
  551:            <<"-record(r, {a,b}).
  552:               f(X, Y) -> #r{a=[K || K <- Y], b=[K || K <- Y]}.
  553:               g(X, Y) -> #r{a=lists:map(fun (K) -> K end, Y),
  554:                             b=lists:map(fun (K) -> K end, Y)}.
  555:               h(X, Y) -> #r{a=case Y of _ when is_list(Y) -> Y end,
  556:                             b=case Y of _ when is_list(Y) -> Y end}.
  557:               i(X, Y) -> #r{a=if is_list(Y) -> Y end, b=if is_list(Y) -> Y end}.
  558:              ">>,
  559:            [warn_unused_vars],
  560:            {warnings,[{2,erl_lint,{unused_var,'X'}},
  561:                       {3,erl_lint,{unused_var,'X'}},
  562:                       {5,erl_lint,{unused_var,'X'}},
  563:                       {7,erl_lint,{unused_var,'X'}}]}},
  564:           {rec3,
  565:            <<"-record(r, {a}).
  566:               t() -> X = 1, #r{a=foo, a=bar, a=qux}.
  567:              ">>,
  568:            [warn_unused_vars],
  569:            {error,[{2,erl_lint,{redefine_field,r,a}},
  570:                    {2,erl_lint,{redefine_field,r,a}}],
  571:                   [{2,erl_lint,{unused_var,'X'}}]}}],
  572:     ?line [] = run(Config, Ts),
  573:     ok.
  574: 
  575: unused_vars_warn_fun(doc) ->
  576:     "Warnings for unused variables in records.";
  577: unused_vars_warn_fun(suite) -> [];
  578: unused_vars_warn_fun(Config) when is_list(Config) ->
  579:     Ts = [{fun1,
  580:            <<"a({A,B}) -> % A unused.
  581:                   fun(A) -> B end; % A shadowed. A unused.
  582:               a([A,B]) ->
  583:                   fun(<<A:B>>, % A shadowed. A unused.
  584:                        <<Q:A>>) -> foo % Q unused.
  585:                   end;
  586:               a({A,B,C,D,E}) ->
  587:                   fun(E) when C == <<A:A>>, <<17:B>> == D -> % E shadowed. E unused.
  588:                           foo
  589:                   end,
  590:                   E;
  591:               a([A,B,C,D,E]) -> % E unused.
  592:                   fun() ->
  593:                           (C == <<A:A>>) and (<<17:B>> == D)
  594:                   end.
  595:            ">>,
  596:            [warn_unused_vars],
  597:            {warnings,[{1,erl_lint,{unused_var,'A'}},
  598:                   {2,erl_lint,{unused_var,'A'}},
  599:                   {2,erl_lint,{shadowed_var,'A','fun'}},
  600:                   {4,erl_lint,{unused_var,'A'}},
  601:                   {4,erl_lint,{shadowed_var,'A','fun'}},
  602:                   {5,erl_lint,{unused_var,'Q'}},
  603:                   {8,erl_lint,{unused_var,'E'}},
  604:                   {8,erl_lint,{shadowed_var,'E','fun'}},
  605: 		  {8,sys_core_fold,useless_building},
  606:                   {12,erl_lint,{unused_var,'E'}}]}},
  607: 
  608:           {fun2,
  609:            <<"u() ->
  610:                   case foo of
  611:                       true ->
  612:                           U = 2;
  613:                       false ->
  614:                           true
  615:                   end,
  616:                   fun(U) -> foo end, % U unused.
  617:                   U; % U unsafe.
  618:               u() ->
  619:                   case foo of
  620:                       true ->
  621:                           U = 2;
  622:                       false ->
  623:                           U = 3
  624:                   end,
  625:                   fun(U) -> foo end, % U shadowed. U unused.
  626:                   U;
  627:               u() ->
  628:                   case foo of
  629:                       true ->
  630:                           U = 2; % U unused.
  631:                       false ->
  632:                           U = 3 % U unused.
  633:                   end,
  634:                   fun(U) -> foo end. % U shadowed. U unused.
  635:            ">>,
  636:            [warn_unused_vars],
  637:            {error,[{9,erl_lint,{unsafe_var,'U',{'case',2}}}],
  638:               [{8,erl_lint,{unused_var,'U'}},
  639:                {17,erl_lint,{unused_var,'U'}},
  640:                {17,erl_lint,{shadowed_var,'U','fun'}},
  641:                {22,erl_lint,{unused_var,'U'}},
  642:                {24,erl_lint,{unused_var,'U'}},
  643:                {26,erl_lint,{unused_var,'U'}},
  644:                {26,erl_lint,{shadowed_var,'U','fun'}}]}}
  645:           ],
  646:     ?line [] = run(Config, Ts),
  647:     ok.
  648: 
  649: unused_vars_OTP_4858(doc) ->
  650:     "Bit syntax, binsize variable used in the same matching.";
  651: unused_vars_OTP_4858(suite) -> [];
  652: unused_vars_OTP_4858(Config) when is_list(Config) ->
  653:     Ts = [{otp_4858,
  654:            <<"objs(<<Size:4/unit:8, B:Size/binary>>) ->
  655:                   B.
  656: 
  657:               fel(<<Size:4/unit:8, B:BadSize/binary>>) -> % BadSize unbound.
  658:                   BadSize.                                % B, Size unused.
  659: 
  660:               r9c_highlight() -> % B, Rest unused.
  661:                  <<Size, B:Size/binary,Rest/binary>> = <<2,\"AB\",3,\"CDE\">>.
  662:            ">>,
  663:            [warn_unused_vars],
  664:            {error,[{4,erl_lint,{unbound_var,'BadSize'}}],
  665:               [{4,erl_lint,{unused_var,'B'}},
  666:                {4,erl_lint,{unused_var,'Size'}},
  667:                {8,erl_lint,{unused_var,'B'}},
  668:                {8,erl_lint,{unused_var,'Rest'}}]}}
  669:          ],
  670:     ?line [] = run(Config, Ts),
  671:     ok.
  672: 
  673: export_vars_warn(doc) ->
  674:     "Warnings for exported variables";
  675: export_vars_warn(suite) -> [];
  676: export_vars_warn(Config) when is_list(Config) ->
  677:     Ts = [{exp1,
  678:            <<"u() ->
  679:                   case foo of
  680:                       1 ->
  681:                           A = 1,
  682:                           B = 2,
  683:                           W = 3, % W unused.
  684:                           Z = 3; % Z unused.
  685:                       2 ->
  686:                           B = 2,
  687:                           Z = 4 % Z unused.
  688:                   end,
  689:                   case bar of
  690:                       true ->
  691:                           A = 17, % A unsafe.
  692:                           X = 3, % X unused.
  693:                           U = 2,
  694:                           U;
  695:                       false ->
  696:                           B = 19, % B exported.
  697:                           U = 3; % U unused.
  698:                       foo ->
  699:                           X = 3,
  700:                           X;
  701:                       bar ->
  702:                           X = 9, % X unused.
  703:                           U = 14 % U unused.
  704:                   end.
  705:            ">>,
  706:            [warn_unused_vars],
  707:            {error,[{14,erl_lint,{unsafe_var,'A',{'case',2}}}],
  708:                   [{6,erl_lint,{unused_var,'W'}},
  709:                    {7,erl_lint,{unused_var,'Z'}},
  710:                    {10,erl_lint,{unused_var,'Z'}},
  711:                    {15,erl_lint,{unused_var,'X'}},
  712:                    {19,erl_lint,{exported_var,'B',{'case',2}}},
  713:                    {20,erl_lint,{unused_var,'U'}},
  714:                    {25,erl_lint,{unused_var,'X'}},
  715:                    {26,erl_lint,{unused_var,'U'}}]}},
  716: 
  717:           {exp2,
  718:            <<"bin(A) ->
  719:                   receive
  720:                       M ->
  721:                            X = M,
  722:                            Y = M,
  723:                            Z = M
  724:                   end,
  725:                   [B || <<B:X>> <- A], % X exported.
  726:                   Y = B, % Y exported. B unbound.
  727:                   [B || B <- Z]. % Z exported. B shadowed.
  728:            ">>,
  729:            [warn_export_vars],
  730:            {error,[{9,erl_lint,{unbound_var,'B'}}],
  731:                   [{8,erl_lint,{exported_var,'X',{'receive',2}}},
  732:                    {9,erl_lint,{exported_var,'Y',{'receive',2}}},
  733:                    {10,erl_lint,{exported_var,'Z',{'receive',2}}},
  734:                    {10,erl_lint,{shadowed_var,'B',generate}}]}},
  735: 
  736:           {exp3,
  737:            <<"bin(A) ->
  738:                   receive
  739:                       M ->
  740:                            X = M,
  741:                            Y = M,
  742:                            Z = M
  743:                   end,
  744:                   [B || <<B:X>> <- A], % (X exported.)
  745:                   Y = B, % Y exported. B unbound.
  746:                   [B || B <- Z]. % (Z exported.) B shadowed.
  747:            ">>,
  748:            [],
  749:            {error,[{9,erl_lint,{unbound_var,'B'}}],
  750:                   [{9,erl_lint,{exported_var,'Y',{'receive',2}}},
  751:                    {10,erl_lint,{shadowed_var,'B',generate}}]}}
  752:          ],
  753:     ?line [] = run(Config, Ts),
  754:     ok.
  755: 
  756: shadow_vars(doc) ->
  757:     "Shadowed variables are tested in other places, but here we test "
  758: 	"that the warning can be turned off.";
  759: shadow_vars(suite) -> [];
  760: shadow_vars(Config) when is_list(Config) ->
  761:     Ts = [{shadow1,
  762: 	   <<"bin(A) ->
  763:                   receive
  764:                       M ->
  765:                            X = M,
  766:                            Y = M,
  767:                            Z = M
  768:                   end,
  769:                   [B || <<B:X>> <- A],
  770:                   Y = B,
  771:                   [B || B <- Z]. % B shadowed.
  772:            ">>,
  773: 	   [nowarn_shadow_vars],
  774: 	   {error,[{9,erl_lint,{unbound_var,'B'}}],
  775: 	    [{9,erl_lint,{exported_var,'Y',{'receive',2}}}]}}],
  776:     
  777:     ?line [] = run(Config, Ts),
  778:     ok.
  779: 
  780: unused_import(doc) ->
  781:     "Test that the 'warn_unused_import' option works.";
  782: unused_import(suite) -> [];
  783: unused_import(Config) when is_list(Config) ->
  784:     Ts = [{imp1,
  785: 	   <<"-import(lists, [map/2,foldl/3]).
  786:               t(L) ->
  787:                  map(fun(X) -> 2*X end, L).
  788:            ">>,
  789: 	   [warn_unused_import],
  790: 	   {warnings,[{1,erl_lint,{unused_import,{{foldl,3},lists}}}]}}],
  791:     ?line [] = run(Config, Ts),
  792:     ok.
  793: 
  794: unused_function(doc) ->
  795:     "Test warnings for unused functions.";
  796: unused_function(suite) -> [];
  797: unused_function(Config) when is_list(Config) ->
  798:     Ts = [{func1,
  799: 	   <<"-export([t/1]).
  800:               t(L) ->
  801:                  lists:map(fun(X) -> 2*X end, L).
  802: 
  803:               fact(N) ->
  804:                 fact_1(N, 1).
  805: 
  806:               fact_1(1, P) -> P;
  807:               fact_1(N, P) -> fact_1(N-1, P*N).
  808:            ">>,
  809: 	   {[]},				%Tuple indicates no 'export_all'.
  810: 	   {warnings,[{5,erl_lint,{unused_function,{fact,1}}},
  811: 		      {8,erl_lint,{unused_function,{fact_1,2}}}]}},
  812: 
  813: 	  %% Turn off warnings for unused functions.
  814: 	  {func2,
  815: 	   <<"-export([t/1]).
  816:               t(L) ->
  817:                  lists:map(fun(X) -> 2*X end, L).
  818: 
  819:               b(X) ->
  820:                 32*X.
  821:            ">>,
  822: 	   {[nowarn_unused_function]},         %Tuple indicates no 'export_all'.
  823: 	   []},
  824: 
  825: 	  %% Turn off warnings for unused functions using a -compile() directive.
  826: 	  {func3,
  827: 	   <<"-export([t/1]).
  828:               -compile(nowarn_unused_function).
  829: 
  830:               t(L) ->
  831:                  lists:map(fun(X) -> 2*X end, L).
  832: 
  833:               b(X) ->
  834:                 32*X.
  835:            ">>,
  836: 	   {[]},		     %Tuple indicates no 'export_all'.
  837: 	   []}],
  838: 
  839:     ?line [] = run(Config, Ts),
  840:     ok.
  841:     
  842: unsafe_vars(doc) ->
  843:     "OTP-4671. Errors for unsafe variables";
  844: unsafe_vars(suite) -> [];
  845: unsafe_vars(Config) when is_list(Config) ->
  846:     Ts = [{unsafe1,
  847:            <<"t() ->
  848:                  (X = true) orelse (Y = false),
  849:                   Y.
  850:            ">>,
  851:            [warn_unused_vars],
  852:            {error,[{3,erl_lint,{unsafe_var,'Y',{'orelse',2}}}],
  853:             [{2,erl_lint,{unused_var,'X'}}]}},
  854:           {unsafe2,
  855:            <<"t2() ->
  856:                   (X = true) orelse (Y = false),
  857:                   X.
  858:            ">>,
  859:            [warn_unused_vars],
  860:            {warnings,[{2,erl_lint,{unused_var,'Y'}}]}},
  861:           {unsafe3,
  862:            <<"t3() ->
  863:                   (X = true) andalso (Y = false),
  864:                   Y.
  865:            ">>,
  866:            [warn_unused_vars],
  867:            {error,[{3,erl_lint,{unsafe_var,'Y',{'andalso',2}}}],
  868:             [{2,erl_lint,{unused_var,'X'}}]}},
  869:           {unsafe4,
  870:            <<"t4() ->
  871:                   (X = true) andalso (true = X),
  872:                   X.
  873:            ">>,
  874:            [warn_unused_vars],
  875:            []},
  876:           {unsafe5,
  877:            <<"t5() ->
  878:                   Y = 3,
  879:                   (X = true) andalso (X = true),
  880:                   {X,Y}.
  881:            ">>,
  882:            [warn_unused_vars],
  883:            []},
  884:           {unsafe6,
  885:            <<"t6() ->
  886:                   X = true,
  887:                   (X = true) andalso (true = X),
  888:                   X.
  889:            ">>,
  890:            [warn_unused_vars],
  891:            []},
  892:           {unsafe7,
  893:            <<"t7() ->
  894:                   (if true -> X = 3; false -> true end) 
  895:                       andalso (X > 2),
  896:                   X.
  897:            ">>,
  898:            [warn_unused_vars],
  899:            {errors,[{3,erl_lint,{unsafe_var,'X',{'if',2}}},
  900:                     {4,erl_lint,{unsafe_var,'X',{'if',2}}}],
  901:             []}}
  902:          ],
  903:     ?line [] = run(Config, Ts),
  904:     ok.
  905: 
  906: unsafe_vars2(doc) ->
  907:     "OTP-4831, seq8202. No warn_unused_vars and unsafe variables";
  908: unsafe_vars2(suite) -> [];
  909: unsafe_vars2(Config) when is_list(Config) ->
  910:     Ts = [{unsafe2_1,
  911:            <<"foo(State) ->
  912:                   case State of
  913:                       true ->
  914:                           if
  915:                               false -> ok;
  916:                               true ->  State1=State
  917:                           end
  918:                   end,
  919:                   State1. % unsafe
  920:            ">>,
  921:            [warn_unused_vars],
  922:            {errors,[{9,erl_lint,{unsafe_var,'State1',{'if',4}}}],[]}},
  923:           {unsafe2_2,
  924:            <<"foo(State) ->
  925:                   case State of
  926:                       true ->
  927:                           if
  928:                               false -> ok;
  929:                               true ->  State1=State
  930:                           end
  931:                   end,
  932:                   State1. % unsafe
  933:            ">>,
  934:            [],
  935:            {errors,[{9,erl_lint,{unsafe_var,'State1',{'if',4}}}],[]}}
  936:          ],
  937:     ?line [] = run(Config, Ts),
  938:     ok.
  939: 
  940: unsafe_vars_try(doc) ->
  941:     "Errors for unsafe variables in try/catch constructs.";
  942: unsafe_vars_try(suite) -> [];
  943: unsafe_vars_try(Config) when is_list(Config) ->
  944:     Ts = [{unsafe_try1,
  945: 	   <<"foo2() ->
  946:                 try self()
  947:                 catch
  948:                   Class:Data -> Result={Class,Data}
  949:                 end,
  950:                 Result.
  951:               foo3a() ->
  952:                 try self() of
  953:                   R -> R
  954:                 catch
  955:                   Class:Data -> Result={Class,Data}
  956:                 end,
  957:                 Result.
  958:               foo3b() ->
  959:                 try self() of
  960:                   Result -> ok
  961:                 catch
  962:                   Class:Data -> {Class,Data}
  963:                 end,
  964:                 Result.
  965:            ">>,
  966: 	   [],
  967: 	   {errors,[{6,erl_lint,{unsafe_var,'Result',{'try',2}}},
  968: 		    {13,erl_lint,{unsafe_var,'Result',{'try',8}}},
  969: 		    {20,erl_lint,{unsafe_var,'Result',{'try',15}}}],
  970: 	    []}},
  971: 	  {unsafe_try2,
  972: 	   <<"foo1a() ->
  973:                 Try = 
  974:                   try self()
  975:                   catch
  976:                     Class:Data -> Rc={Class,Data}
  977:                   after
  978:                     Ra=ok
  979:                   end,
  980:                 {Try,Rc,Ra}.
  981:               foo1b() ->
  982:                 Try = 
  983:                   try self() of
  984:                     R -> R
  985:                   catch
  986:                     Class:Data -> Rc={Class,Data}
  987:                   after
  988:                     Ra=R
  989:                   end,
  990:                 {Try,Rc,Ra}.
  991:               foo2() ->
  992:                 Try = 
  993:                   try self() of
  994:                     R -> Ro=R
  995:                   catch
  996:                     Class:Data -> {Class,Data}
  997:                   after
  998:                     Ra=R
  999:                   end,
 1000:                 {Try,Ro,Ra}.
 1001:               foo3() ->
 1002:                 Try = 
 1003:                   try self() of
 1004:                     R -> Ro=R
 1005:                   catch
 1006:                     Class:Data -> Rc={Class,Data}
 1007:                   after
 1008:                     Ra=R
 1009:                   end,
 1010:                 {Try,R,Ro,Rc,Ra}.
 1011:            ">>,
 1012: 	   [],
 1013: 	   {errors,[{9,erl_lint,{unsafe_var,'Ra',{'try',3}}},
 1014:                     {9,erl_lint,{unsafe_var,'Rc',{'try',3}}},
 1015: 		    {17,erl_lint,{unsafe_var,'R',{'try',12}}},
 1016: 		    {19,erl_lint,{unsafe_var,'Ra',{'try',12}}},
 1017: 		    {19,erl_lint,{unsafe_var,'Rc',{'try',12}}},
 1018: 		    {27,erl_lint,{unsafe_var,'R',{'try',22}}},
 1019: 		    {29,erl_lint,{unsafe_var,'Ra',{'try',22}}},
 1020: 		    {29,erl_lint,{unsafe_var,'Ro',{'try',22}}},
 1021: 		    {37,erl_lint,{unsafe_var,'R',{'try',32}}},
 1022: 		    {39,erl_lint,{unsafe_var,'R',{'try',32}}},
 1023: 		    {39,erl_lint,{unsafe_var,'Ra',{'try',32}}},
 1024:                     {39,erl_lint,{unsafe_var,'Rc',{'try',32}}},
 1025:                     {39,erl_lint,{unsafe_var,'Ro',{'try',32}}}],
 1026: 	    []}},
 1027: 	  {unsafe_try3,
 1028: 	   <<"foo1(X) ->
 1029:                 Try = 
 1030:                   try R=self()
 1031:                   catch
 1032:                     Class:Data -> Rc={X,R,Class,Data}
 1033:                   end,
 1034:                 {X,Try,Rc}.
 1035: 	      foo2(X) ->
 1036:                 Try = 
 1037:                   try R=self() of
 1038:                     RR -> Ro={X,R,RR}
 1039:                   catch
 1040:                     Class:Data -> {X,R,RR,Ro,Class,Data}
 1041:                   end,
 1042:                 {X,Try,R,RR,Ro,Class,Data}.
 1043: 	      foo3(X) ->
 1044:                 Try = 
 1045:                   try R=self() of
 1046:                     RR -> {X,R,RR}
 1047:                   catch
 1048:                     Class:Data -> {X,R,RR,Class,Data}
 1049:                   after
 1050:                     Ra={X,R,RR,Class,Data}
 1051:                   end,
 1052:                 {X,Try,R,RR,Ra,Class,Data}.
 1053:            ">>,
 1054: 	   [],
 1055: 	   {errors,[{5,erl_lint,{unsafe_var,'R',{'try',3}}},
 1056: 		    {7,erl_lint,{unsafe_var,'Rc',{'try',3}}},
 1057: 		    {11,erl_lint,{unsafe_var,'R',{'try',10}}},
 1058: 		    {13,erl_lint,{unbound_var,'RR'}},
 1059: 		    {13,erl_lint,{unbound_var,'Ro'}},
 1060: 		    {13,erl_lint,{unsafe_var,'R',{'try',10}}},
 1061: 		    {15,erl_lint,{unsafe_var,'Class',{'try',10}}},
 1062: 		    {15,erl_lint,{unsafe_var,'Data',{'try',10}}},
 1063: 		    {15,erl_lint,{unsafe_var,'R',{'try',10}}},
 1064: 		    {15,erl_lint,{unsafe_var,'RR',{'try',10}}},
 1065: 		    {15,erl_lint,{unsafe_var,'Ro',{'try',10}}},
 1066: 		    {19,erl_lint,{unsafe_var,'R',{'try',18}}},
 1067: 		    {21,erl_lint,{unbound_var,'RR'}},
 1068: 		    {21,erl_lint,{unsafe_var,'R',{'try',18}}},
 1069: 		    {23,erl_lint,{unsafe_var,'Class',{'try',18}}},
 1070: 		    {23,erl_lint,{unsafe_var,'Data',{'try',18}}},
 1071: 		    {23,erl_lint,{unsafe_var,'R',{'try',18}}},
 1072: 		    {23,erl_lint,{unsafe_var,'RR',{'try',18}}},
 1073: 		    {25,erl_lint,{unsafe_var,'Class',{'try',18}}},
 1074:                     {25,erl_lint,{unsafe_var,'Data',{'try',18}}},
 1075: 		    {25,erl_lint,{unsafe_var,'R',{'try',18}}},
 1076: 		    {25,erl_lint,{unsafe_var,'RR',{'try',18}}},
 1077: 		    {25,erl_lint,{unsafe_var,'Ra',{'try',18}}}],
 1078: 	    []}},
 1079: 	  {unsafe_try4,
 1080: 	   <<"foo1(X) ->
 1081:                 Try = 
 1082:                   try R=self() of
 1083:                     RR -> Ro={X,R,RR}
 1084:                   catch
 1085:                     Class:Data -> Rc={X,R,RR,Ro,Class,Data}
 1086:                   after
 1087:                     Ra={X,R,RR,Ro,Rc,Class,Data}
 1088:                   end,
 1089:                 {X,Try,R,RR,Ro,Rc,Ra,Class,Data}.
 1090:            ">>,
 1091: 	   [],
 1092: 	   {errors,[{4,erl_lint,{unsafe_var,'R',{'try',3}}},
 1093: 		    {6,erl_lint,{unbound_var,'RR'}},
 1094: 		    {6,erl_lint,{unbound_var,'Ro'}},
 1095: 		    {6,erl_lint,{unsafe_var,'R',{'try',3}}},
 1096: 		    {8,erl_lint,{unsafe_var,'Class',{'try',3}}},
 1097: 		    {8,erl_lint,{unsafe_var,'Data',{'try',3}}},
 1098: 		    {8,erl_lint,{unsafe_var,'R',{'try',3}}},
 1099: 		    {8,erl_lint,{unsafe_var,'RR',{'try',3}}},
 1100: 		    {8,erl_lint,{unsafe_var,'Rc',{'try',3}}},
 1101: 		    {8,erl_lint,{unsafe_var,'Ro',{'try',3}}},
 1102: 		    {10,erl_lint,{unsafe_var,'Class',{'try',3}}},
 1103:                     {10,erl_lint,{unsafe_var,'Data',{'try',3}}},
 1104: 		    {10,erl_lint,{unsafe_var,'R',{'try',3}}},
 1105: 		    {10,erl_lint,{unsafe_var,'RR',{'try',3}}},
 1106: 		    {10,erl_lint,{unsafe_var,'Ra',{'try',3}}},
 1107: 		    {10,erl_lint,{unsafe_var,'Rc',{'try',3}}},
 1108: 		    {10,erl_lint,{unsafe_var,'Ro',{'try',3}}}],
 1109: 	    []}},
 1110:           {unsafe_try5,
 1111:            <<"bang() ->
 1112:                 case 1 of
 1113:                   nil ->
 1114:                     Acc = 2;
 1115:                   _ ->
 1116:                     try
 1117:                       Acc = 3,
 1118:                       Acc
 1119:                     catch _:_ ->
 1120:                       ok
 1121:                     end
 1122:                 end,
 1123:                 Acc.
 1124:            ">>,
 1125:            [],
 1126:            {errors,[{13,erl_lint,{unsafe_var,'Acc',{'try',6}}}],[]}}],
 1127:         ?line [] = run(Config, Ts),
 1128:     ok.
 1129: 
 1130: guard(doc) ->
 1131:     "OTP-4670. Guards, is_record in particular.";
 1132: guard(suite) -> [];
 1133: guard(Config) when is_list(Config) ->
 1134:     %% Well, these could be plain code...
 1135:     Ts = [{guard1,
 1136:            <<"-record(apa, {}).
 1137:               t(A) when atom(A) ->
 1138:                   atom;
 1139:               t(A) when binary(A) ->
 1140:                   binary;
 1141:               t(A) when constant(A) ->
 1142:                   constant;
 1143:               t(A) when float(A) ->
 1144:                   float;
 1145:               t(A) when function(A) ->
 1146:                   function;
 1147:               t(A) when integer(A) ->
 1148:                   integer;
 1149:               t(A) when is_atom(A) ->
 1150:                   is_atom;
 1151:               t(A) when is_binary(A) ->
 1152:                   is_binary;
 1153:               t(A) when is_constant(A) ->
 1154:                   is_constant;
 1155:               t(A) when is_float(A) ->
 1156:                   is_float;
 1157:               t(A) when is_function(A) ->
 1158:                   is_function;
 1159:               t(A) when is_integer(A) ->
 1160:                   is_integer;
 1161:               t(A) when is_list(A) ->
 1162:                   is_list;
 1163:               t(A) when is_number(A) ->
 1164:                   is_number;
 1165:               t(A) when is_pid(A) ->
 1166:                   is_pid;
 1167:               t(A) when is_port(A) ->
 1168:                   is_port;
 1169:               t(A) when is_record(A, apa) ->
 1170:                   is_record;
 1171:               t(A) when is_record(A, apa, 1) ->
 1172:                   is_record;
 1173:               t(A) when is_reference(A) ->
 1174:                   is_reference;
 1175:               t(A) when is_tuple(A) ->
 1176:                   is_tuple;
 1177:               t(A) when list(A) ->
 1178:                   list;
 1179:               t(A) when number(A) ->
 1180:                   number;
 1181:               t(A) when pid(A) ->
 1182:                   pid;
 1183:               t(A) when port(A) ->
 1184:                   port;
 1185:               t(A) when record(A, apa) ->
 1186:                   record;
 1187:               t(A) when reference(A) ->
 1188:                   reference;
 1189:               t(A) when tuple(A) ->
 1190:                   tuple.
 1191:            ">>,
 1192:            [nowarn_obsolete_guard],
 1193:            {error,
 1194: 	    [{6,erl_lint,illegal_guard_expr},{18,erl_lint,illegal_guard_expr}],
 1195: 	    [{18,erl_lint,{removed,{erlang,is_constant,1},
 1196: 			   "Removed in R13B"}}]}},
 1197:           {guard2,
 1198:            <<"-record(apa,{}).
 1199:               t1(A) when atom(A), atom(A) ->
 1200:                   atom;
 1201:               t1(A) when binary(A), binary(A) ->
 1202:                   binary;
 1203:               t1(A) when constant(A), constant(A) ->
 1204:                   constant;
 1205:               t1(A) when float(A), float(A) ->
 1206:                   float;
 1207:               t1(A) when function(A), function(A) ->
 1208:                   function;
 1209:               t1(A) when integer(A), integer(A) ->
 1210:                   integer;
 1211:               t1(A) when is_atom(A), is_atom(A) ->
 1212:                   is_atom;
 1213:               t1(A) when is_binary(A), is_binary(A) ->
 1214:                   is_binary;
 1215:               t1(A) when is_constant(A), is_constant(A) ->
 1216:                   is_constant;
 1217:               t1(A) when is_float(A), is_float(A) ->
 1218:                   is_float;
 1219:               t1(A) when is_function(A), is_function(A) ->
 1220:                   is_function;
 1221:               t1(A) when is_integer(A), is_integer(A) ->
 1222:                   is_integer;
 1223:               t1(A) when is_list(A), is_list(A) ->
 1224:                   is_list;
 1225:               t1(A) when is_number(A), is_number(A) ->
 1226:                   is_number;
 1227:               t1(A) when is_pid(A), is_pid(A) ->
 1228:                   is_pid;
 1229:               t1(A) when is_port(A), is_port(A) ->
 1230:                   is_port;
 1231:               t1(A) when is_record(A, apa), is_record(A, apa) ->
 1232:                   is_record;
 1233:               t1(A) when is_record(A, apa, 1), is_record(A, apa, 1) ->
 1234:                   is_record;
 1235:               t1(A) when is_reference(A), is_reference(A) ->
 1236:                   is_reference;
 1237:               t1(A) when is_tuple(A), is_tuple(A) ->
 1238:                   is_tuple;
 1239:               t1(A) when list(A), list(A) ->
 1240:                   list;
 1241:               t1(A) when number(A), number(A) ->
 1242:                   number;
 1243:               t1(A) when pid(A), pid(A) ->
 1244:                   pid;
 1245:               t1(A) when port(A), port(A) ->
 1246:                   port;
 1247:               t1(A) when record(A, apa), record(A, apa) ->
 1248:                   record;
 1249:               t1(A) when reference(A), reference(A) ->
 1250:                   reference;
 1251:               t1(A) when tuple(A), tuple(A) ->
 1252:                   tuple.
 1253:            ">>,
 1254:            [nowarn_obsolete_guard],
 1255: 	   {error,[{6,erl_lint,illegal_guard_expr},
 1256: 		   {6,erl_lint,illegal_guard_expr},
 1257: 		   {18,erl_lint,illegal_guard_expr},
 1258: 		   {18,erl_lint,illegal_guard_expr}],
 1259: 	    [{18,erl_lint,{removed,{erlang,is_constant,1},
 1260: 			   "Removed in R13B"}},
 1261:              {18,erl_lint,{removed,{erlang,is_constant,1},
 1262: 			   "Removed in R13B"}}]}},
 1263:           {guard3,
 1264:            <<"-record(apa,{}).
 1265:               t2(A) when atom(A); atom(A) ->
 1266:                   atom;
 1267:               t2(A) when binary(A); binary(A) ->
 1268:                   binary;
 1269:               t2(A) when float(A); float(A) ->
 1270:                   float;
 1271:               t2(A) when function(A); function(A) ->
 1272:                   function;
 1273:               t2(A) when integer(A); integer(A) ->
 1274:                   integer;
 1275:               t2(A) when is_atom(A); is_atom(A) ->
 1276:                   is_atom;
 1277:               t2(A) when is_binary(A); is_binary(A) ->
 1278:                   is_binary;
 1279:               t2(A) when is_float(A); is_float(A) ->
 1280:                   is_float;
 1281:               t2(A) when is_function(A); is_function(A) ->
 1282:                   is_function;
 1283:               t2(A) when is_integer(A); is_integer(A) ->
 1284:                   is_integer;
 1285:               t2(A) when is_list(A); is_list(A) ->
 1286:                   is_list;
 1287:               t2(A) when is_number(A); is_number(A) ->
 1288:                   is_number;
 1289:               t2(A) when is_pid(A); is_pid(A) ->
 1290:                   is_pid;
 1291:               t2(A) when is_port(A); is_port(A) ->
 1292:                   is_port;
 1293:               t2(A) when is_record(A, apa); is_record(A, apa) ->
 1294:                   is_record;
 1295:               t2(A) when is_record(A, gurka, 1); is_record(A, gurka, 1) ->
 1296:                   is_record;
 1297:               t2(A) when is_reference(A); is_reference(A) ->
 1298:                   is_reference;
 1299:               t2(A) when is_tuple(A); is_tuple(A) ->
 1300:                   is_tuple;
 1301:               t2(A) when list(A); list(A) ->
 1302:                   list;
 1303:               t2(A) when number(A); number(A) ->
 1304:                   number;
 1305:               t2(A) when pid(A); pid(A) ->
 1306:                   pid;
 1307:               t2(A) when port(A); port(A) ->
 1308:                   port;
 1309:               t2(A) when record(A, apa); record(A, apa) ->
 1310:                   record;
 1311:               t2(A) when reference(A); reference(A) ->
 1312:                   reference;
 1313:               t2(A) when tuple(A); tuple(A) ->
 1314:                   tuple.
 1315:            ">>,
 1316:            [nowarn_obsolete_guard],
 1317: 	   []},
 1318:           {guard4,
 1319:            <<"-record(apa, {}).
 1320:               t3(A) when float(A) or float(A) -> % coercing... (badarg)
 1321:                   float;
 1322:               t3(A) when is_atom(A) or is_atom(A) ->
 1323:                   is_atom;
 1324:               t3(A) when is_binary(A) or is_binary(A) ->
 1325:                   is_binary;
 1326:               t3(A) when is_float(A) or is_float(A) ->
 1327:                   is_float;
 1328:               t3(A) when is_function(A) or is_function(A) ->
 1329:                   is_function;
 1330:               t3(A) when is_integer(A) or is_integer(A) ->
 1331:                   is_integer;
 1332:               t3(A) when is_list(A) or is_list(A) ->
 1333:                   is_list;
 1334:               t3(A) when is_number(A) or is_number(A) ->
 1335:                   is_number;
 1336:               t3(A) when is_pid(A) or is_pid(A) ->
 1337:                   is_pid;
 1338:               t3(A) when is_port(A) or is_port(A) ->
 1339:                   is_port;
 1340:               t3(A) when is_record(A, apa) or is_record(A, apa) ->
 1341:                   is_record;
 1342:               t3(A) when is_record(A, apa, 1) or is_record(A, apa, 1) ->
 1343:                   is_record;
 1344:               t3(A) when is_reference(A) or is_reference(A) ->
 1345:                   is_reference;
 1346:               t3(A) when is_tuple(A) or is_tuple(A) ->
 1347:                   is_tuple.
 1348:            ">>,
 1349:            [nowarn_obsolete_guard],
 1350:            []}],
 1351:     ?line [] = run(Config, Ts),
 1352:     Ts1 = [{guard5,
 1353:             <<"-record(apa, {}).
 1354:                t3(A) when record(A, {apa}) ->
 1355:                    foo;
 1356:                t3(A) when is_record(A, {apa}) ->
 1357:                    foo;
 1358:                t3(A) when erlang:is_record(A, {apa}) ->
 1359:                    foo;
 1360:                t3(A) when is_record(A, {apa}, 1) ->
 1361:                    foo;
 1362:                t3(A) when erlang:is_record(A, {apa}, 1) ->
 1363:                    foo;
 1364:                t3(A) when is_record(A, apa, []) ->
 1365:                    foo;
 1366:                t3(A) when erlang:is_record(A, apa, []) ->
 1367:                    foo;
 1368:                t3(A) when record(A, apa) ->
 1369:                    foo;
 1370:                t3(A) when is_record(A, apa) ->
 1371:                    foo;
 1372:                t3(A) when erlang:is_record(A, apa) ->
 1373:                    foo.
 1374:             ">>,
 1375:             [warn_unused_vars, nowarn_obsolete_guard],
 1376:             {errors,[{2,erl_lint,illegal_guard_expr},
 1377: 		     {4,erl_lint,illegal_guard_expr},
 1378: 		     {6,erl_lint,illegal_guard_expr},
 1379: 		     {8,erl_lint,illegal_guard_expr},
 1380: 		     {10,erl_lint,illegal_guard_expr},
 1381: 		     {12,erl_lint,illegal_guard_expr},
 1382: 		     {14,erl_lint,illegal_guard_expr}],
 1383: 	     []}},
 1384:            {guard6,
 1385:             <<"-record(apa,{a=a,b=foo:bar()}).
 1386:               apa() ->
 1387:                  [X || X <- [], #apa{a = a} == {r,X,foo}];
 1388:               apa() ->
 1389:                  [X || X <- [], #apa{b = b} == {r,X,foo}];
 1390:               apa() ->
 1391:                  [X || X <- [], #ful{a = a} == {r,X,foo}].
 1392:             ">>,
 1393:             [],
 1394:             {errors,[{7,erl_lint,{undefined_record,ful}}],
 1395:              []}},
 1396:            {guard7,
 1397:             <<"-record(apa,{}).
 1398:                t() ->
 1399:                [X || X <- [1,#apa{},3], (3+is_record(X, apa)) or 
 1400:                                         (is_record(X, apa)*2)].
 1401:             ">>,
 1402:             [],
 1403:             []},
 1404: 	   {guard8,
 1405: 	    <<"t(A) when erlang:is_foobar(A) -> ok;
 1406: 	      t(A) when A ! ok -> ok;
 1407: 	      t(A) when A ++ [x] -> ok."
 1408: 	    >>,
 1409: 	    [],
 1410: 	    {errors,[{1,erl_lint,illegal_guard_expr},
 1411: 		     {2,erl_lint,illegal_guard_expr},
 1412: 		     {3,erl_lint,illegal_guard_expr}],[]}}
 1413: 	  ],
 1414:     ?line [] = run(Config, Ts1),
 1415:     ok.
 1416: 
 1417: otp_4886(doc) ->
 1418:     "OTP-4886. Calling is_record with given record name.";
 1419: otp_4886(suite) -> [];
 1420: otp_4886(Config) when is_list(Config) ->
 1421:     Ts = [{otp_4886,
 1422:            <<"t() ->
 1423:                   X = {foo},
 1424:                   is_record(X, foo),
 1425:                   erlang:is_record(X, foo),
 1426:                   {erlang,is_record}(X, foo),
 1427:                   %% Note: is_record/3 does not verify that the record is defined,
 1428:                   %% so the following lines should give no errors.
 1429:                   is_record(X, foo, 1),
 1430:                   erlang:is_record(X, foo, 1),
 1431:                   {erlang,is_record}(X, foo, 1).
 1432:              ">>,
 1433:            [],
 1434:            {errors,[{3,erl_lint,{undefined_record,foo}},
 1435:                     {4,erl_lint,{undefined_record,foo}},
 1436:                     {5,erl_lint,{undefined_record,foo}}],
 1437:             []}}],
 1438:     ?line [] = run(Config, Ts),
 1439:     ok.
 1440: 
 1441: otp_4988(doc) ->
 1442:     "OTP-4988. Error when in-lining non-existent functions.";
 1443: otp_4988(suite) -> [];
 1444: otp_4988(Config) when is_list(Config) ->
 1445:     Ts = [{otp_4988,
 1446:            <<"-compile({inline, [{f,3},{f,4},{f,2},{f,a},{1,foo}]}).
 1447:               -compile({inline, {g,1}}).
 1448:               -compile({inline, {g,12}}).
 1449:               -compile(inline).
 1450:               -compile({inline_size,100}).
 1451: 
 1452:               f(A, B) ->
 1453:                   {g(A), B}.
 1454: 
 1455:               g(A) ->
 1456:                   {A}.
 1457:              ">>,
 1458:            [],
 1459:            {errors,[{1,erl_lint,{bad_inline,{1,foo}}},
 1460:                     {1,erl_lint,{bad_inline,{f,3}}},
 1461:                     {1,erl_lint,{bad_inline,{f,4}}},
 1462:                     {1,erl_lint,{bad_inline,{f,a}}},
 1463:                     {3,erl_lint,{bad_inline,{g,12}}}],
 1464:             []}}],
 1465:     ?line [] = run(Config, Ts),
 1466:     ok.
 1467: 
 1468: otp_5091(doc) ->
 1469:     "OTP-5091. Patterns and the bit syntax: invalid warnings.";
 1470: otp_5091(suite) -> [];
 1471: otp_5091(Config) when is_list(Config) ->
 1472:     Ts = [{otp_5091_1,
 1473:            <<"t() ->
 1474:                  [{Type, Value} || <<Type:16, _Len:16, 
 1475:                                     Value:_Len/binary>> <- []].
 1476:              ">>,
 1477:            [],
 1478:            []},
 1479:           {otp_5091_2,
 1480:            <<"t() ->
 1481:                  %% This one has always been handled OK:
 1482:                  <<Type:16, _Len:16, 
 1483:                       Value:_Len/binary>> = <<18:16, 9:16, \"123456789\">>,
 1484:                  {Type, Value}.
 1485:              ">>,
 1486:            [],
 1487:            []},
 1488:           {otp_5091_3,
 1489:            <<"t() ->
 1490:                  fun(<<Type:16, _Len:16, Value:_Len/binary>>) ->
 1491:                      {Type, Value}
 1492:                  end.
 1493:              ">>,
 1494:            [],
 1495:            []},
 1496:           {otp_5091_4,
 1497:            <<"t() ->
 1498:                  L = 8,
 1499:                  F = fun(<<A:L,B:A>>) -> B end,
 1500:                  F(<<16:8, 7:16>>).
 1501:              ">>,
 1502:            [],
 1503:            []},
 1504:           {otp_5091_5,
 1505:            <<"t() ->
 1506:                  L = 8,
 1507:                  F = fun(<<L: % L shadowed.
 1508:                             L,
 1509:                            B:
 1510:                             L>>) -> B end,
 1511:                  F(<<16:8, 7:16>>).
 1512:              ">>,
 1513:            [],
 1514:            {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}},
 1515:           {otp_5091_6,
 1516:            <<"t(A) ->
 1517:                  (fun(<<L:16,M:L,N:M>>) -> ok end)(A).
 1518:              ">>,
 1519:            [],
 1520:            {warnings,[{2,erl_lint,{unused_var,'N'}}]}},
 1521:           {otp_5091_7,
 1522:            <<"t() ->
 1523:                   U = 8, 
 1524:                   (fun(<<U: % U shadowed.
 1525:                           U>>) -> U end)(<<32:8>>).
 1526:              ">>,
 1527:            [],
 1528:            {warnings,[{3,erl_lint,{shadowed_var,'U','fun'}}]}},
 1529:           {otp_5091_8,
 1530:            <<"t() ->
 1531:                   [X || <<A:8,
 1532:                           B:A>> <- [],
 1533:                         <<X:8>> <- [B]].
 1534:              ">>,
 1535:            [],
 1536:            []},
 1537:           {otp_5091_9,
 1538:            <<"t() ->
 1539:                   L = 8,
 1540:                   F = fun(<<L: % Shadow.
 1541:                            L,
 1542:                            L:
 1543:                            L,
 1544:                            L:
 1545:                            L
 1546:                            >>) ->
 1547:                               L
 1548:                       end,
 1549:                   F(<<16:8, 8:16, 32:8>>).
 1550:              ">>,
 1551:            [],
 1552:            {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}},
 1553:           {otp_5091_10,
 1554:            <<"t() ->
 1555:                 L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B.
 1556:              ">>,
 1557:            [],
 1558:            []},
 1559:           {otp_5091_11,
 1560:            <<"t() ->
 1561:                 fun(<<L:16,L:L,L:L>>) -> ok end.
 1562:              ">>,
 1563:            [],
 1564:            []},
 1565:           {otp_5091_12,
 1566:            <<"t([A,B]) ->
 1567:                  fun(<<A:B>>, % A shadowed and unused
 1568:                      <<Q:A>>) -> foo % Q unused. 'outer' A is used.
 1569:                  end.
 1570:              ">>,
 1571:            [],
 1572:            {warnings,[{2,erl_lint,{unused_var,'A'}},
 1573:                       {2,erl_lint,{shadowed_var,'A','fun'}},
 1574:                       {3,erl_lint,{unused_var,'Q'}}]}},
 1575:           {otp_5091_13,
 1576:            <<"t([A,B]) -> % A unused, B unused
 1577:                  fun({A,B}, % A shadowed, B unused, B shadowed
 1578:                      {Q,A}) -> foo % Q unused. 'inner' A is used
 1579:                  end.
 1580:              ">>,
 1581:            [],
 1582:            {warnings,[{1,erl_lint,{unused_var,'A'}},
 1583:                       {1,erl_lint,{unused_var,'B'}},
 1584:                       {2,erl_lint,{unused_var,'B'}},
 1585:                       {2,erl_lint,{shadowed_var,'A','fun'}},
 1586:                       {2,erl_lint,{shadowed_var,'B','fun'}},
 1587:                       {3,erl_lint,{unused_var,'Q'}}]}},
 1588:           {otp_5091_14,
 1589:            <<"t() ->
 1590:                  A = 4,
 1591:                  fun(<<A: % shadowed, unused
 1592:                        A>>) -> 2 end.
 1593:              ">>,
 1594:            [],
 1595:            {warnings,[{3,erl_lint,{unused_var,'A'}},
 1596:                       {3,erl_lint,{shadowed_var,'A','fun'}}]}},
 1597:           {otp_5091_15,
 1598:            <<"t() ->
 1599:                  A = 4, % unused
 1600:                  fun(<<A:8, % shadowed
 1601:                        16:A>>) -> 2 end.
 1602:              ">>,
 1603:            [],
 1604:            {warnings,[{2,erl_lint,{unused_var,'A'}},
 1605:                       {3,erl_lint,{shadowed_var,'A','fun'}}]}},
 1606:           {otp_5091_16,
 1607:            <<"t() ->
 1608:                  A = 4,
 1609:                  fun(<<8:A, % 
 1610:                        A:8>>) -> 7 end. % shadowed, unused
 1611:              ">>,
 1612:            [],
 1613:            {warnings,[{4,erl_lint,{unused_var,'A'}},
 1614:                       {4,erl_lint,{shadowed_var,'A','fun'}}]}},
 1615:           {otp_5091_17,
 1616:            <<"t() ->
 1617:                  L = 16,
 1618:                  fun(<<L: % shadow
 1619:                        L>>, % 'outer' L
 1620:                      <<L: % shadow and match
 1621:                        L>>) -> % 'outer' L
 1622:                          a
 1623:                  end.
 1624:              ">>,
 1625:            [],
 1626:            {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}},
 1627:           {otp_5091_18,
 1628:            <<"t() ->
 1629:                  L = 4,      % L unused
 1630:                  fun({L,     % L shadowed
 1631:                       L},
 1632:                      {L,
 1633:                       L}) ->
 1634:                          a
 1635:                  end.
 1636:              ">>,
 1637:            [],
 1638:            {warnings,[{2,erl_lint,{unused_var,'L'}},
 1639:                       {3,erl_lint,{shadowed_var,'L','fun'}}]}},
 1640:           {otp_5091_19,
 1641:            <<"t() ->
 1642:                  L = 4,
 1643:                  [L || <<L: % shadowed
 1644:                          L, 
 1645:                          L:
 1646:                          L>> <- []].
 1647:              ">>,
 1648:            [],
 1649:            {warnings,[{3,erl_lint,{shadowed_var,'L',generate}}]}},
 1650:           {otp_5091_20,
 1651:            <<"t() ->
 1652:                  L = 4, % L unused.
 1653:                  [1 || L <- []]. % L unused, L shadowed.
 1654:              ">>,
 1655:            [],
 1656:            {warnings,[{2,erl_lint,{unused_var,'L'}},
 1657:                       {3,erl_lint,{unused_var,'L'}},
 1658:                       {3,erl_lint,{shadowed_var,'L',generate}}]}},
 1659:           {otp_5091_21,
 1660:            <<"t() ->
 1661:                  L = 4,
 1662:                  [1 || L <- [L]]. % L shadowed. L unused.
 1663:              ">>,
 1664:            [],
 1665:            {warnings,[{3,erl_lint,{unused_var,'L'}},
 1666:                       {3,erl_lint,{shadowed_var,'L',generate}}]}},
 1667:           {otp_5091_22,
 1668:            <<"t() ->
 1669:                  L = 4, % unused
 1670:                  fun(L) -> L end. % shadowed
 1671:              ">>,
 1672:            [],
 1673:            {warnings,[{2,erl_lint,{unused_var,'L'}},
 1674:                       {3,erl_lint,{shadowed_var,'L','fun'}}]}},
 1675:           {otp_5091_23,
 1676:            <<"t([A,A]) -> a.">>, [], []},
 1677:           {otp_5091_24,
 1678:            <<"t({A,A}) -> a.">>, [], []},
 1679:           {otp_5091_25,
 1680:            <<"-record(r, {f1,f2}).
 1681:               t(#r{f1 = A, f2 = A}) -> a.">>, [], []}],
 1682: 
 1683:     ?line [] = run(Config, Ts),
 1684:     ok.
 1685: 
 1686: otp_5276(doc) ->
 1687:     "OTP-5276. Check the 'deprecated' attributed.";
 1688: otp_5276(suite) -> [];
 1689: otp_5276(Config) when is_list(Config) ->
 1690:     Ts = [{otp_5276_1,
 1691:           <<"-deprecated([{frutt,0,next_version}]).
 1692:              -deprecated([{does_not_exist,1}]).
 1693:              -deprecated('foo bar').
 1694:              -deprecated(module).
 1695:              -deprecated([{f,'_'}]).
 1696:              -deprecated([{t,0}]).
 1697:              -deprecated([{t,'_',eventually}]).
 1698:              -deprecated([{'_','_',never}]).
 1699:              -deprecated([{{badly,formed},1}]).
 1700:              -deprecated([{'_','_',next_major_release}]).
 1701:              -deprecated([{atom_to_list,1}]).
 1702:              -export([t/0]).
 1703:              frutt() -> ok.
 1704:              t() -> ok.
 1705:             ">>,
 1706:            {[]},
 1707:            {error,[{1,erl_lint,{bad_deprecated,{frutt,0}}},
 1708:                    {2,erl_lint,{bad_deprecated,{does_not_exist,1}}},
 1709:                    {3,erl_lint,{invalid_deprecated,'foo bar'}},
 1710:                    {5,erl_lint,{bad_deprecated,{f,'_'}}},
 1711:                    {8,erl_lint,{invalid_deprecated,{'_','_',never}}},
 1712:                    {9,erl_lint,{invalid_deprecated,{{badly,formed},1}}},
 1713: 		   {11,erl_lint,{bad_deprecated,{atom_to_list,1}}}],
 1714:             [{13,erl_lint,{unused_function,{frutt,0}}}]}}],
 1715:     ?line [] = run(Config, Ts),
 1716:     ok.
 1717: 
 1718: otp_5917(doc) ->
 1719:     "OTP-5917. Check the 'deprecated' attributed.";
 1720: otp_5917(suite) -> [];
 1721: otp_5917(Config) when is_list(Config) ->
 1722:     Ts = [{otp_5917_1,
 1723:           <<"-compile(export_all).
 1724: 
 1725:              -deprecated({t,0}).
 1726: 
 1727:              t() ->
 1728:                  foo.
 1729:             ">>,
 1730:            {[]},
 1731:            []}],
 1732:     ?line [] = run(Config, Ts),
 1733:     ok.
 1734: 
 1735: otp_6585(doc) ->
 1736:     "OTP-6585. Check the deprecated guards list/1, pid/1, ....";
 1737: otp_6585(suite) -> [];
 1738: otp_6585(Config) when is_list(Config) ->
 1739:     Ts = [{otp_6585_1,
 1740:           <<"-compile(export_all).
 1741: 
 1742:              -record(r, {}).
 1743: 
 1744:              f(A) when list(A) -> list;
 1745:              f(R) when record(R, r) -> rec;
 1746:              f(P) when pid(P) -> pid.
 1747: 
 1748:              t() ->
 1749:                  f([]).
 1750:             ">>,
 1751:            [warn_obsolete_guard],
 1752:            {warnings,[{5,erl_lint,{obsolete_guard,{list,1}}},
 1753:                       {6,erl_lint,{obsolete_guard,{record,2}}},
 1754:                       {7,erl_lint,{obsolete_guard,{pid,1}}}]}}],
 1755:     ?line [] = run(Config, Ts),
 1756:     ok.
 1757: 
 1758: otp_5338(doc) ->
 1759:     "OTP-5338. Bad warning in record initialization.";
 1760: otp_5338(suite) -> [];
 1761: otp_5338(Config) when is_list(Config) ->
 1762:     %% OTP-5878: variables like X are no longer allowed in initialisations
 1763:     Ts = [{otp_5338,
 1764:           <<"-record(c, {a = <<X:7/binary-unit:8>>}).
 1765:               t() ->
 1766:                   X = <<\"hejsans\">>,
 1767:                   #c{}.
 1768:             ">>,
 1769:            [],
 1770:            {error,[{1,erl_lint,{unbound_var,'X'}}],
 1771:                   [{3,erl_lint,{unused_var,'X'}}]}}],
 1772:     ?line [] = run(Config, Ts),
 1773:     ok.
 1774: 
 1775: otp_5362(doc) ->
 1776:     "OTP-5362. deprecated_function, "
 1777:     "{nowarn_unused_funtion,FAs}, 'better' line numbers.";
 1778: otp_5362(suite) -> [];
 1779: otp_5362(Config) when is_list(Config) ->
 1780:     Ts = [{otp_5362_1,
 1781:           <<"-include_lib(\"stdlib/include/qlc.hrl\").
 1782: 
 1783:              -file(?FILE, 1000).
 1784: 
 1785:              t() ->
 1786:                  qlc:q([X || X <- [],
 1787:                              begin A = 3, true end]).
 1788:             ">>,
 1789:            {[warn_unused_vars]},
 1790:            {warnings,[{1002,erl_lint,{unused_function,{t,0}}},
 1791:                       {1004,erl_lint,{unused_var,'A'}}]}},
 1792: 
 1793:           {otp_5362_2,
 1794:           <<"-export([inline/0]).
 1795: 
 1796:              -import(lists, [a/1,b/1]). % b/1 is not used
 1797: 
 1798:              -compile([{inline,{inl,7}}]).    % undefined
 1799:              -compile([{inline,[{inl,17}]}]). % undefined
 1800:              -compile([{inline,{inl,1}}]).    % OK
 1801: 
 1802:              foop() ->   % unused function
 1803:                  a([]),  % used import, OK
 1804:                  fipp(). % undefined
 1805: 
 1806:              inline() ->
 1807:                  inl(foo).
 1808: 
 1809:              inl(_) ->
 1810:                  true.
 1811: 
 1812:              not_used() ->      % unused function
 1813:                  true.
 1814: 
 1815:              -compile({nowarn_unused_function,[{and_not_used,2}]}). % unknown 
 1816:              and_not_used(_) -> % unused function
 1817:                  foo.
 1818: 
 1819:              -compile({nowarn_unused_function,{unused_function,2}}).
 1820:              unused_function(_, _) ->
 1821:                  ok.
 1822:            ">>,
 1823:           {[warn_unused_vars, warn_unused_import]},
 1824:            {error,[{5,erl_lint,{bad_inline,{inl,7}}},
 1825:                    {6,erl_lint,{bad_inline,{inl,17}}},
 1826:                    {11,erl_lint,{undefined_function,{fipp,0}}},
 1827:                    {22,erl_lint,{bad_nowarn_unused_function,{and_not_used,2}}}],
 1828:             [{3,erl_lint,{unused_import,{{b,1},lists}}},
 1829:              {9,erl_lint,{unused_function,{foop,0}}},
 1830:              {19,erl_lint,{unused_function,{not_used,0}}},
 1831:              {23,erl_lint,{unused_function,{and_not_used,1}}}]}},
 1832: 
 1833:           {otp_5362_3,
 1834:            <<"-record(a, {x,
 1835:                           x}).
 1836:               -record(a, {x,
 1837:                           X}). % erl_parse
 1838:               -record(a, [x,
 1839:                           x]). % erl_parse
 1840:               -record(ok, {a,b}).
 1841: 
 1842:               -record(r, {a = #ok{}, 
 1843:                           b = (#ok{})#ok.a}).
 1844: 
 1845:               t() ->
 1846:                   {#a{},
 1847:                    #nix{},
 1848:                    #ok{nix = []},
 1849:                    #ok{Var = 4}, 
 1850:                    #r{}
 1851:                   }.
 1852:            ">>,
 1853:            {[nowarn_unused_function]},
 1854:            {errors2, [{4,erl_parse,"bad record field"},
 1855:                       {5,erl_parse,"bad record declaration"}],
 1856:                      [{2,erl_lint,{redefine_field,a,x}},
 1857:                       {14,erl_lint,{undefined_record,nix}},
 1858:                       {15,erl_lint,{undefined_field,ok,nix}},
 1859:                       {16,erl_lint,{field_name_is_variable,ok,'Var'}}]}},
 1860: 
 1861: 	  %% Nowarn_bif_clash has changed behaviour as local functions
 1862: 	  %% nowdays supersede auto-imported BIFs, why nowarn_bif_clash in itself generates an error
 1863: 	  %% (OTP-8579) /PaN
 1864:           {otp_5362_4,
 1865:            <<"-compile(nowarn_deprecated_function).
 1866:               -compile(nowarn_bif_clash).
 1867:               spawn(A) ->
 1868:                   erlang:hash(A, 3000),
 1869:                   spawn(A).
 1870:            ">>,
 1871:            {[nowarn_unused_function, 
 1872:              warn_deprecated_function,
 1873:              warn_bif_clash]},
 1874:            {error,
 1875:             [{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}],
 1876: 	    [{4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
 1877: 			  "in a future release"}}]}},
 1878: 
 1879:           {otp_5362_5,
 1880:            <<"-compile(nowarn_deprecated_function).
 1881:               -compile(nowarn_bif_clash).
 1882:               spawn(A) ->
 1883:                   erlang:hash(A, 3000),
 1884:                   spawn(A).
 1885:            ">>,
 1886:            {[nowarn_unused_function]},
 1887: 	   {errors,
 1888:             [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
 1889: 
 1890:           %% The special nowarn_X are not affected by general warn_X.
 1891:           {otp_5362_6,
 1892:            <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}).
 1893:               -compile({nowarn_bif_clash,{spawn,1}}).
 1894:               spawn(A) ->
 1895:                   erlang:hash(A, 3000),
 1896:                   spawn(A).
 1897:            ">>,
 1898:            {[nowarn_unused_function, 
 1899:              warn_deprecated_function, 
 1900:              warn_bif_clash]},
 1901:            {errors,
 1902:             [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
 1903: 
 1904:           {otp_5362_7,
 1905:            <<"-export([spawn/1]).
 1906:               -compile({nowarn_deprecated_function,{erlang,hash,2}}).
 1907:               -compile({nowarn_bif_clash,{spawn,1}}).
 1908:               -compile({nowarn_bif_clash,{spawn,2}}). % bad
 1909:               -compile([{nowarn_deprecated_function, 
 1910:                                 [{erlang,hash,-1},{3,hash,-1}]}, % 2 bad
 1911:                      {nowarn_deprecated_function, {{a,b,c},hash,-1}}]). % bad
 1912:               spawn(A) ->
 1913:                   erlang:hash(A, 3000),
 1914:                   spawn(A).
 1915:            ">>,
 1916:            {[nowarn_unused_function]},
 1917:            {error,[{3,erl_lint,disallowed_nowarn_bif_clash},
 1918: 		   {4,erl_lint,disallowed_nowarn_bif_clash},
 1919: 		   {4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}],
 1920:             [{5,erl_lint,{bad_nowarn_deprecated_function,{3,hash,-1}}},
 1921:              {5,erl_lint,{bad_nowarn_deprecated_function,{erlang,hash,-1}}},
 1922:              {5,erl_lint,{bad_nowarn_deprecated_function,{{a,b,c},hash,-1}}}]}
 1923:            },
 1924: 
 1925:           {otp_5362_8,
 1926:            <<"-export([spawn/1]).
 1927:               -compile(warn_deprecated_function).
 1928:               -compile(warn_bif_clash).
 1929:               spawn(A) ->
 1930:                   erlang:hash(A, 3000),
 1931:                   spawn(A).
 1932:            ">>,
 1933:            {[nowarn_unused_function,
 1934:              {nowarn_bif_clash,{spawn,1}}]}, % has no effect
 1935:            {warnings,
 1936:             [{5,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
 1937: 			  "in a future release"}}]}},
 1938: 
 1939:           {otp_5362_9,
 1940:            <<"-include_lib(\"stdlib/include/qlc.hrl\").
 1941:               -record(a, {x = qlc:q([{X,Y} || {X} <- [],{Y} <- [],X =:= Y])}).
 1942:               -export([t/0]).              
 1943:               t() -> #a{}.
 1944:           ">>,
 1945:            {[]},
 1946:            []},
 1947: 
 1948:           {otp_5362_10,
 1949:            <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}).
 1950:               -compile({nowarn_bif_clash,{spawn,1}}).
 1951:               -import(x,[spawn/1]).
 1952:               spin(A) ->
 1953:                   erlang:hash(A, 3000),
 1954:                   spawn(A).
 1955:            ">>,
 1956:            {[nowarn_unused_function,
 1957:              warn_deprecated_function,
 1958:              warn_bif_clash]},
 1959:            {errors,
 1960:             [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
 1961: 
 1962: 	  {call_deprecated_function,
 1963: 	   <<"t(X) -> erlang:hash(X, 2000).">>,
 1964: 	   [],
 1965: 	   {warnings,
 1966:             [{1,erl_lint,{deprecated,{erlang,hash,2},
 1967: 			  {erlang,phash2,2},"in a future release"}}]}},
 1968: 
 1969: 	  {call_removed_function,
 1970: 	   <<"t(X) -> regexp:match(X).">>,
 1971: 	   [],
 1972: 	   {warnings,
 1973:             [{1,erl_lint,{removed,{regexp,match,1},
 1974: 			  "removed in R15; use the re module instead"}}]}}
 1975: 
 1976: 	 ],
 1977: 
 1978:     ?line [] = run(Config, Ts),
 1979:     ok.
 1980: 
 1981: otp_5371(doc) ->
 1982:     "OTP-5371. Aliases for bit syntax expressions are no longer allowed.";
 1983: otp_5371(suite) -> [];
 1984: otp_5371(Config) when is_list(Config) ->
 1985:     Ts = [{otp_5371_1,
 1986:            <<"t(<<A:8>> = <<B:8>>) ->
 1987:                   {A,B}.
 1988:              ">>,
 1989: 	   [],
 1990: 	   {errors,[{1,erl_lint,illegal_bin_pattern}],[]}},
 1991: 	  {otp_5371_2,
 1992:            <<"x([<<A:8>>] = [<<B:8>>]) ->
 1993:                   {A,B}.
 1994:               y({a,<<A:8>>} = {b,<<B:8>>}) ->
 1995:                   {A,B}.
 1996:              ">>,
 1997: 	   [],
 1998: 	   {errors,[{1,erl_lint,illegal_bin_pattern},
 1999: 		    {3,erl_lint,illegal_bin_pattern}],[]}},
 2000: 	  {otp_5371_3,
 2001:            <<"-record(foo, {a,b,c}).
 2002:               -record(bar, {x,y,z}).
 2003:               -record(buzz, {x,y}).
 2004:               a(#foo{a = <<X:8>>} = #bar{x = <<Y:8>>}) ->
 2005:                   {X,Y}.
 2006:               b(#foo{b = <<X:8>>} = #foo{b = <<Y:4,Z:4>>}) ->
 2007:                   {X,Y,Z}.
 2008:               c(#foo{a = <<X:8>>} = #buzz{x = <<Y:8>>}) ->
 2009:                   {X,Y}.
 2010:               d(#foo{a=x,b = <<X:8>>} = #buzz{y = <<Y:8>>}) ->
 2011:                   {X,Y}.
 2012:               e(#foo{a=x,b = <<X:8>>} = #buzz{x=glurf,y = <<Y:8>>}) ->
 2013:                   {X,Y}.
 2014:              ">>,
 2015: 	   [],
 2016: 	   {errors,[{4,erl_lint,illegal_bin_pattern},
 2017: 		    {6,erl_lint,illegal_bin_pattern},
 2018: 		    {8,erl_lint,illegal_bin_pattern},
 2019: 		    {10,erl_lint,illegal_bin_pattern},
 2020: 		    {12,erl_lint,illegal_bin_pattern}],[]}},
 2021: 	  {otp_5371_4,
 2022:            <<"-record(foo, {a,b,c}).
 2023:               -record(bar, {x,y,z}).
 2024:               -record(buzz, {x,y}).
 2025:               a(#foo{a = <<X:8>>,b=x} = #foo{b = <<Y:8>>}) ->
 2026:                   {X,Y}.
 2027:               b(#foo{a = <<X:8>>} = #bar{y = <<Y:4,Z:4>>}) ->
 2028:                   {X,Y,Z}.
 2029:               c(#foo{a = <<X:8>>} = #buzz{y = <<Y:8>>}) ->
 2030:                   {X,Y}.
 2031:              ">>,
 2032: 	   [],
 2033: 	   {warnings,[{4,v3_core,nomatch},
 2034: 		      {6,v3_core,nomatch},
 2035: 		      {8,v3_core,nomatch}]}}
 2036: 	 ],
 2037:     ?line [] = run(Config, Ts),
 2038:     ok.
 2039: 
 2040: otp_7227(doc) -> "OTP_7227. Some aliases for bit syntax expressions were still allowed.";
 2041: otp_7227(Config) when is_list(Config) ->
 2042:     Ts = [{otp_7227_1,
 2043:            <<"t([<<A:8>> = {C,D} = <<B:8>>]) ->
 2044:                   {A,B,C,D}.
 2045:              ">>,
 2046: 	   [],
 2047: 	   {errors,[{1,erl_lint,illegal_bin_pattern}],[]}},
 2048: 	  {otp_7227_2,
 2049:            <<"t([(<<A:8>> = {C,D}) = <<B:8>>]) ->
 2050:                   {A,B,C,D}.
 2051:              ">>,
 2052: 	   [],
 2053: 	   {errors,[{1,erl_lint,illegal_bin_pattern}],[]}},
 2054: 	  {otp_7227_3,
 2055:            <<"t([(<<A:8>> = {C,D}) = (<<B:8>> = <<C:8>>)]) ->
 2056:                   {A,B,C,D}.
 2057:              ">>,
 2058: 	   [],
 2059: 	   {errors,[{1,erl_lint,illegal_bin_pattern},
 2060: 		    {1,erl_lint,illegal_bin_pattern},
 2061: 		    {1,erl_lint,illegal_bin_pattern}],[]}},
 2062: 	  {otp_7227_4,
 2063:            <<"t(Val) ->
 2064:                   <<A:8>> = <<B:8>> = Val,
 2065:                   {A,B}.
 2066:              ">>,
 2067: 	   [],
 2068: 	   {errors,[{2,erl_lint,illegal_bin_pattern}],[]}},
 2069: 	  {otp_7227_5,
 2070:            <<"t(Val) ->
 2071:                   <<A:8>> = X = <<B:8>> = Val,
 2072:                   {A,B,X}.
 2073:              ">>,
 2074: 	   [],
 2075: 	   {errors,[{2,erl_lint,illegal_bin_pattern}],[]}},
 2076: 	  {otp_7227_6,
 2077:            <<"t(X, Y) ->
 2078:                   <<A:8>> = <<X:4,Y:4>>,
 2079:                   A.
 2080:              ">>,
 2081: 	   [],
 2082: 	   []},
 2083: 	  {otp_7227_7,
 2084:            <<"t(Val) ->
 2085:                   (<<A:8>> = X) = (<<B:8>> = <<A:4,B:4>>) = Val,
 2086:                   {A,B,X}.
 2087:              ">>,
 2088: 	   [],
 2089: 	   {errors,[{2,erl_lint,illegal_bin_pattern},
 2090: 		    {2,erl_lint,illegal_bin_pattern},
 2091: 		    {2,erl_lint,illegal_bin_pattern}],[]}},
 2092: 	  {otp_7227_8,
 2093:            <<"t(Val) ->
 2094:                   (<<A:8>> = X) = (Y = <<B:8>>) = Val,
 2095:                   {A,B,X,Y}.
 2096:              ">>,
 2097: 	   [],
 2098: 	   {errors,[{2,erl_lint,illegal_bin_pattern}],[]}},
 2099: 	  {otp_7227_9,
 2100:            <<"t(Val) ->
 2101:                   (Z = <<A:8>> = X) = (Y = <<B:8>> = W) = Val,
 2102:                   {A,B,X,Y,Z,W}.
 2103:              ">>,
 2104: 	   [],
 2105: 	   {errors,[{2,erl_lint,illegal_bin_pattern}],[]}}
 2106: 	 ],
 2107:     ?line [] = run(Config, Ts),
 2108:     ok.
 2109: 
 2110: otp_5494(doc) ->
 2111:     "OTP-5494. Warnings for functions exported more than once.";
 2112: otp_5494(suite) -> [];
 2113: otp_5494(Config) when is_list(Config) ->
 2114:     Ts = [{otp_5494_1,
 2115:            <<"-export([t/0]).
 2116:               -export([t/0]).
 2117:               t() -> a.
 2118:              ">>,
 2119:            [],
 2120:            {warnings,[{2,erl_lint,{duplicated_export,{t,0}}}]}}],
 2121:     ?line [] = run(Config, Ts),
 2122:     ok.
 2123: 
 2124: otp_5644(doc) ->
 2125:     "OTP-5644. M:F/A in record initialization.";
 2126: otp_5644(suite) -> [];
 2127: otp_5644(Config) when is_list(Config) ->
 2128:     %% This test is a no-op. Although {function,mfa,i,1} was
 2129:     %% transformed into {function,Line,i,1} by copy_expr, the module
 2130:     %% was never checked (Line is the line number).
 2131:     %% (OTP-5878: somewhat modified.)
 2132:     Ts = [{otp_5644,
 2133:           <<"-record(c, {a = fun ?MODULE:i/1(17)}).
 2134:               t() ->
 2135:                   #c{}.
 2136: 
 2137:               i(X) ->
 2138:                   X.
 2139:             ">>,
 2140:            [],
 2141:            []}],
 2142:     ?line [] = run(Config, Ts),
 2143:     ok.
 2144: 
 2145: otp_5878(doc) ->
 2146:     "OTP-5878. Record declaration: forward references, introduced variables.";
 2147: otp_5878(suite) -> [];
 2148: otp_5878(Config) when is_list(Config) ->
 2149:     Ts = [{otp_5878_10,
 2150:           <<"-record(rec1, {a = #rec2{}}).
 2151:              -record(rec2, {a = #rec1{}}).
 2152:              t() ->#rec1{}.
 2153:             ">>,
 2154:            [warn_unused_record],
 2155:            {error,[{1,erl_lint,{undefined_record,rec2}}],
 2156:                   [{2,erl_lint,{unused_record,rec2}}]}},
 2157: 
 2158:           {otp_5878_20,
 2159:            <<"-record(r1, {a = begin A = 4, {A,B} end}). % B unbound
 2160:               -record(r2, {e = begin A = 3, #r1{} end}).
 2161:               t() -> #r2{}.
 2162:              ">>,
 2163:            [warn_unused_record],
 2164:            {error,[{1,erl_lint,{unbound_var,'B'}},
 2165:                    {1,erl_lint,{variable_in_record_def,'A'}},
 2166:                    {2,erl_lint,{variable_in_record_def,'A'}}],
 2167:             [{1,erl_lint,{unused_record,r1}}]}},
 2168: 
 2169:           {otp_5878_30,
 2170:            <<"-record(r1, {t = case foo of _ -> 3 end}).
 2171:               -record(r2, {a = case foo of A -> A; _ -> 3 end}).
 2172:               -record(r3, {a = case foo of A -> A end}).
 2173:               t() -> {#r1{},#r2{},#r3{}}.
 2174:              ">>,
 2175:            [warn_unused_record],
 2176:            {errors,[{2,erl_lint,{variable_in_record_def,'A'}},
 2177:                     {3,erl_lint,{variable_in_record_def,'A'}}],
 2178:             []}},
 2179: 
 2180:           {otp_5878_40,
 2181:            <<"-record(r1, {foo = A}). % A unbound
 2182:               -record(r2, {a = fun(X) -> X end(3)}).
 2183:               -record(r3, {a = [X || X <- [1,2,3]]}).
 2184:               t() -> {#r1{},#r2{},#r3{}}.
 2185:              ">>,
 2186:            [warn_unused_record],
 2187:            {errors,[{1,erl_lint,{unbound_var,'A'}}],[]}},
 2188: 
 2189:           {otp_5878_50,
 2190:            <<"-record(r1, {a = {A, % A unbound
 2191:                                 A}}). % A unbound
 2192:               -record(r2, {a = begin case foo of 
 2193:                                          A -> A
 2194:                                      end,
 2195:                                      A
 2196:                                 end}).
 2197:               -record(r3, {a = fun(X) ->
 2198:                                        case foo of
 2199:                                            A -> A
 2200:                                        end
 2201:                                end
 2202:                           }).
 2203:               -record(r4, {a = case foo of
 2204:                                    foo ->
 2205:                                        case foo of
 2206:                                            A -> A
 2207:                                        end;
 2208:                                    _ -> 
 2209:                                        bar
 2210:                                end}).
 2211:               t() -> {#r1{},#r2{},#r3{},#r4{}}.
 2212:              ">>,
 2213:            [warn_unused_record],
 2214:            {error,[{1,erl_lint,{unbound_var,'A'}},
 2215:                    {2,erl_lint,{unbound_var,'A'}},
 2216:                    {4,erl_lint,{variable_in_record_def,'A'}},
 2217:                    {17,erl_lint,{variable_in_record_def,'A'}}],
 2218:             [{8,erl_lint,{unused_var,'X'}}]}},
 2219: 
 2220:           {otp_5878_60,
 2221:            <<"-record(r1, {a = fun(NotShadowing) -> NotShadowing end}).
 2222:               t() ->
 2223:                   NotShadowing = 17,
 2224:                   {#r1{}, NotShadowing}.
 2225:              ">>,
 2226:            [warn_unused_record],
 2227:            []},
 2228: 
 2229:           {otp_5878_70,
 2230:            <<"-record(r1, {a = fun(<<X:8>>) -> X end,
 2231:                            b = case <<17:8>> of
 2232:                                    <<_:Y>> -> Y;
 2233:                                    <<Y:8>> -> 
 2234:                                        Y
 2235:                                end}).
 2236:               t() -> #r1{}.
 2237:              ">>,
 2238:            [warn_unused_record],
 2239:            {errors,[{3,erl_lint,{unbound_var,'Y'}},
 2240:                     {4,erl_lint,{variable_in_record_def,'Y'}}],
 2241:             []}},
 2242: 
 2243:           {otp_5878_80,
 2244:            <<"-record(r, {a = [X || {A,Y} <- [{1,2},V={3,4}],
 2245:                                     begin Z = [1,2,3], true end,
 2246:                                     X <- Z ++ [A,Y]]}).
 2247:               t() ->#r{}.
 2248:              ">>,
 2249:            [warn_unused_record],
 2250:            {warnings,[{1,erl_lint,{unused_var,'V'}}]}},
 2251: 
 2252:           {otp_5878_90,
 2253:            <<"-record(r, {a = foo()}). % unused
 2254: 
 2255:               t() -> ok.
 2256:              ">>,
 2257:            [warn_unused_record],
 2258:            {error,[{1,erl_lint,{undefined_function,{foo,0}}}],
 2259:             [{1,erl_lint,{unused_record,r}}]}}
 2260: 
 2261:          ],
 2262:     ?line [] = run(Config, Ts),
 2263: 
 2264:     Abstr = <<"-module(lint_test, [A, B]).
 2265:             ">>,
 2266:     {errors,[{1,erl_lint,pmod_unsupported}],[]} =
 2267:         run_test2(Config, Abstr, [warn_unused_record]),
 2268: 
 2269:     QLC1 = <<"-module(lint_test).
 2270:               -include_lib(\"stdlib/include/qlc.hrl\").
 2271:               -export([t/0]).
 2272:               -record(r1, {a = qlc:e(qlc:q([X || X <- [1,2,3]]))}).
 2273:               -record(r2, {a = qlc:q([X || X <- [1,2,3]])}).
 2274:               -record(r3, {a = qlc:q([X || {A,Y} <- [{1,2},V={3,4}],
 2275:                                            begin Z = [1,2,3], true end,
 2276:                                            X <- Z ++ [A,Y]])}).
 2277:               t() -> {#r1{},#r2{},#r3{}}.
 2278:              ">>,
 2279:     ?line {error,[{8,qlc,{used_generator_variable,'A'}},
 2280:                   {8,qlc,{used_generator_variable,'Y'}},
 2281:                   {8,qlc,{used_generator_variable,'Z'}}],
 2282:            [{6,erl_lint,{unused_var,'V'}}]} = 
 2283:         run_test2(Config, QLC1, [warn_unused_record]),
 2284: 
 2285:     Ill1 = <<"-module(lint_test).
 2286:               -export([t/0]).
 2287:               -record(r, {a = true}).
 2288:               -record(r1, {a,b}).
 2289:               -record(r2, {a = #r1{a = true}}).
 2290:               -record(r3, {a = A}). % A is unbound
 2291:               -record(r4, {a = dict:new()}).
 2292: 
 2293:               t() ->
 2294:                   case x() of
 2295:                       _ when (#r{})#r.a ->
 2296:                           a; 
 2297:                       _ when (#r4{})#r.a -> % illegal
 2298:                           b;
 2299:                       _ when (#r3{q = 5})#r.a -> % no warning for unbound A
 2300:                           q;
 2301:                       _ when (#r{q = 5})#r.a ->
 2302:                           a; 
 2303:                       _ when (((#r{a = #r2{}})#r.a)#r2.a)#r1.a ->
 2304:                           b;
 2305:                       _ when #r{a = dict:new()} -> % illegal
 2306:                           c; 
 2307:                       _ when l() > 3 -> % illegal, does not use l/0...
 2308:                           d;
 2309:                       _ ->
 2310:                           w
 2311:                   end.
 2312: 
 2313:               l() ->
 2314:                   foo.
 2315: 
 2316:               x() ->
 2317:                   bar.
 2318:               ">>,
 2319:    
 2320:     ?line {errors,[{6,erl_lint,{unbound_var,'A'}},
 2321:                    {13,erl_lint,illegal_guard_expr},
 2322:                    {15,erl_lint,{undefined_field,r3,q}},
 2323:                    {17,erl_lint,{undefined_field,r,q}},
 2324:                    {21,erl_lint,illegal_guard_expr},
 2325:                    {23,erl_lint,{illegal_guard_local_call,{l,0}}}],
 2326:            []} = 
 2327:         run_test2(Config, Ill1, [warn_unused_record]),
 2328: 
 2329:     Ill2 = <<"-module(lint_test).
 2330:               -export([t/0]).
 2331:               t() ->
 2332:                   case x() of
 2333:                       _ when l() 
 2334:                              or
 2335:                              l() ->
 2336:                           foo
 2337:                   end.
 2338:              ">>,
 2339:     ?line {errors,[{4,erl_lint,{undefined_function,{x,0}}},
 2340:                    {5,erl_lint,illegal_guard_expr},
 2341:                    {7,erl_lint,illegal_guard_expr}],
 2342:            []} = 
 2343:         run_test2(Config, Ill2, [warn_unused_record]),
 2344:     
 2345:     Ill3 = <<"t() -> ok.">>,
 2346:     ?line {errors,[{1,erl_lint,undefined_module}],[]} = 
 2347:         run_test2(Config, Ill3, [warn_unused_record]),
 2348: 
 2349:     Usage1 = <<"-module(lint_test).
 2350:                 -export([t/0]).
 2351:                 -record(u1, {a}).
 2352:                 -record(u2, {a = #u1{}}).
 2353:                 -record(u3, {a}). % unused
 2354:                 -record(u4, {a = #u3{}}). % unused
 2355: 
 2356:                 t() ->
 2357:                     {#u2{}}.
 2358:                ">>,
 2359:     ?line {warnings,[{5,erl_lint,{unused_record,u3}},
 2360:                      {6,erl_lint,{unused_record,u4}}]} = 
 2361:         run_test2(Config, Usage1, [warn_unused_record]),
 2362: 
 2363:     Usage2 = <<"-module(lint_test).
 2364:                 -export([t/0]).
 2365:                 -record(u1, {a}).
 2366:                 -record(u2, {a = #u1{}}).
 2367:                 -file(\"some_file.hrl\", 1).
 2368:                 -record(u3, {a}). % unused, but on other file
 2369:                 -record(u4, {a = #u3{}}). % -\"-
 2370: 
 2371:                 t() ->
 2372:                     {#u2{}}.
 2373:                ">>,
 2374:     ?line [] = run_test2(Config, Usage2, [warn_unused_record]),
 2375: 
 2376:     %% This a completely different story...
 2377:     %% The linter checks if qlc.hrl hasn't been included
 2378:     QLC2 = <<"-module(lint_test).
 2379:               -import(qlc, [q/2]).
 2380:               -export([t/0]).
 2381: 
 2382:               t() ->
 2383:                   H1 = qlc:q([X || X <- [1,2]]),
 2384:                   H2 = qlc:q([X || X <- [1,2]], []),
 2385:                   H3 = q([X || X <- [1,2]], []),
 2386:                   {H1,H2,H3}.
 2387:              ">>,
 2388:     ?line {warnings,[{6,erl_lint,{missing_qlc_hrl,1}},
 2389:                      {7,erl_lint,{missing_qlc_hrl,2}},
 2390:                      {8,erl_lint,{missing_qlc_hrl,2}}]} = 
 2391:         run_test2(Config, QLC2, [warn_unused_record]),
 2392: 
 2393:     %% Records that are used by types are not unused.
 2394:     %% (Thanks to Fredrik Thulin and Kostis Sagonas.)
 2395:     UsedByType = <<"-module(t).
 2396:                     -export([foo/1]).
 2397:                     -record(sipurl,  {host :: string()}).
 2398:                     -record(keylist, {list = [] :: [_]}).
 2399:                     -type sip_headers() :: #keylist{}.
 2400:                     -record(request, {uri :: #sipurl{}, header :: sip_headers()}).
 2401: 
 2402:                     foo(#request{}) -> ok.
 2403:                   ">>,
 2404:     ?line [] = run_test2(Config, UsedByType, [warn_unused_record]),
 2405: 
 2406:     ok.
 2407: 
 2408: otp_6885(doc) ->
 2409:     "OTP-6885. Binary fields in bit syntax matching is now only allowed at the end.";
 2410: otp_6885(suite) -> [];
 2411: otp_6885(Config) when is_list(Config) ->
 2412:     Ts = <<"-module(otp_6885).
 2413:             -export([t/1]).
 2414:             t(<<_/binary,I>>) -> I;
 2415:             t(<<X/binary,I:X>>) -> I;
 2416: 	    t(<<B/binary,T/binary>>) -> {B,T}.
 2417: 
 2418:             build(A, B) ->
 2419:                <<A/binary,B/binary>>.
 2420: 
 2421:             foo(<<\"abc\"/binary>>) ->
 2422:                ok;
 2423:             foo(<<\"abc\":13/integer>>) ->
 2424:                ok;
 2425:             foo(<<\"abc\"/float>>) ->
 2426:                ok;
 2427:             foo(<<\"abc\":19>>) ->
 2428:                ok;
 2429:             foo(<<\"abc\"/utf8>>) ->
 2430:                ok;
 2431:             foo(<<\"abc\"/utf16>>) ->
 2432:                ok;
 2433:             foo(<<\"abc\"/utf32>>) ->
 2434:                ok.
 2435: 
 2436:            ">>,
 2437:     ?line {errors,[{3,erl_lint,unsized_binary_not_at_end},
 2438: 		   {4,erl_lint,unsized_binary_not_at_end},
 2439: 		   {5,erl_lint,unsized_binary_not_at_end},
 2440: 		   {10,erl_lint,typed_literal_string},
 2441: 		   {12,erl_lint,typed_literal_string},
 2442: 		   {14,erl_lint,typed_literal_string},
 2443: 		   {16,erl_lint,typed_literal_string}],
 2444: 	   []} = run_test2(Config, Ts, []),
 2445:     ok.
 2446: 
 2447: otp_10436(doc) ->
 2448:     "OTP-6885. Warnings for opaque types.";
 2449: otp_10436(suite) -> [];
 2450: otp_10436(Config) when is_list(Config) ->
 2451:     Ts = <<"-module(otp_10436).
 2452:             -export_type([t1/0]).
 2453:             -opaque t1() :: {i, integer()}.
 2454:             -opaque t2() :: {a, atom()}.
 2455:          ">>,
 2456:     {warnings,[{4,erl_lint,{not_exported_opaque,{t2,0}}},
 2457:                {4,erl_lint,{unused_type,{t2,0}}}]} =
 2458:         run_test2(Config, Ts, []),
 2459:     Ts2 = <<"-module(otp_10436_2).
 2460:              -export_type([t1/0, t2/0]).
 2461:              -opaque t1() :: term().
 2462:              -opaque t2() :: any().
 2463:          ">>,
 2464:     {warnings,[{3,erl_lint,{underspecified_opaque,{t1,0}}},
 2465:                {4,erl_lint,{underspecified_opaque,{t2,0}}}]} =
 2466:         run_test2(Config, Ts2, []),
 2467:     ok.
 2468: 
 2469: otp_11254(doc) ->
 2470:     "OTP-11254. Warnings for opaque types.";
 2471: otp_11254(suite) -> [];
 2472: otp_11254(Config) when is_list(Config) ->
 2473:     Ts = <<"-module(p2).
 2474:             -export([manifest/2]).
 2475:             manifest(Module, Name) ->
 2476:               fun Module:Nine/1.
 2477:          ">>,
 2478:     {error,[{4,erl_lint,{unbound_var,'Nine'}}],
 2479:      [{3,erl_lint,{unused_var,'Name'}}]} =
 2480:         run_test2(Config, Ts, []),
 2481:     ok.
 2482: 
 2483: export_all(doc) ->
 2484:     "OTP-7392. Warning for export_all.";
 2485: export_all(Config) when is_list(Config) ->
 2486:     Ts = <<"-module(export_all_module).
 2487:             -compile([export_all]).
 2488: 
 2489:             id(I) -> I.
 2490:            ">>,
 2491:     ?line [] = run_test2(Config, Ts, []),
 2492:     ?line {warnings,[{2,erl_lint,export_all}]} =
 2493: 	run_test2(Config, Ts, [warn_export_all]),
 2494:     ok.
 2495: 
 2496: bif_clash(doc) ->
 2497:     "Test warnings for functions that clash with BIFs.";
 2498: bif_clash(suite) -> [];
 2499: bif_clash(Config) when is_list(Config) ->
 2500:     Ts = [{clash1,
 2501:            <<"t(X) ->
 2502:                   size(X).
 2503: 
 2504:               %% No warning for the following calls, since they
 2505:               %% are unambigous.
 2506:               b(X) ->
 2507:                   erlang:size(X).
 2508: 
 2509:               c(X) ->
 2510:                   ?MODULE:size(X).
 2511: 
 2512:               size({N,_}) ->
 2513:                 N.
 2514:              ">>,
 2515:            [],
 2516: 	   {errors,[{2,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}},
 2517: 
 2518: 	  %% Verify that warnings can not be turned off in the old way.
 2519: 	  {clash2,
 2520:            <<"-export([t/1,size/1]).
 2521:               t(X) ->
 2522:                   size(X).
 2523: 
 2524:               size({N,_}) ->
 2525:                 N.
 2526: 
 2527:               %% My own abs/1 function works on lists too. From R14 this really works.
 2528:               abs([H|T]) when $a =< H, H =< $z -> [H-($a-$A)|abs(T)];
 2529:               abs([H|T]) -> [H|abs(T)];
 2530:               abs([]) -> [];
 2531:               abs(X) -> erlang:abs(X).
 2532:              ">>,
 2533: 	   {[nowarn_unused_function,nowarn_bif_clash]},
 2534: 	   {errors,[{erl_lint,disallowed_nowarn_bif_clash}],[]}},
 2535: 	  %% As long as noone calls an overridden BIF, it's totally OK
 2536: 	  {clash3,
 2537:            <<"-export([size/1]).
 2538:               size({N,_}) ->
 2539:                 N;
 2540:               size(X) ->
 2541:                 erlang:size(X).
 2542:              ">>,
 2543: 	   [],
 2544: 	   []},
 2545: 	  %% But this is totally wrong - meaning of the program changed in R14, so this is an error
 2546: 	  {clash4,
 2547:            <<"-export([size/1]).
 2548:               size({N,_}) ->
 2549:                 N;
 2550:               size(X) ->
 2551:                 size(X).
 2552:              ">>,
 2553: 	   [],
 2554: 	   {errors,[{5,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}},
 2555: 	  %% For a post R14 bif, its only a warning
 2556: 	  {clash5,
 2557:            <<"-export([binary_part/2]).
 2558:               binary_part({B,_},{X,Y}) ->
 2559:                 binary_part(B,{X,Y});
 2560:               binary_part(B,{X,Y}) ->
 2561:                 binary:part(B,X,Y).
 2562:              ">>,
 2563: 	   [],
 2564: 	   {warnings,[{3,erl_lint,{call_to_redefined_bif,{binary_part,2}}}]}},
 2565: 	  %% If you really mean to call yourself here, you can "unimport" size/1
 2566: 	  {clash6,
 2567:            <<"-export([size/1]).
 2568:               -compile({no_auto_import,[size/1]}).
 2569:               size([]) ->
 2570:                 0;
 2571:               size({N,_}) ->
 2572:                 N;
 2573:               size([_|T]) ->
 2574:                 1+size(T).
 2575:              ">>,
 2576: 	   [],
 2577: 	   []},
 2578: 	  %% Same for the post R14 autoimport warning
 2579: 	  {clash7,
 2580:            <<"-export([binary_part/2]).
 2581:               -compile({no_auto_import,[binary_part/2]}).
 2582:               binary_part({B,_},{X,Y}) ->
 2583:                 binary_part(B,{X,Y});
 2584:               binary_part(B,{X,Y}) ->
 2585:                 binary:part(B,X,Y).
 2586:              ">>,
 2587: 	   [],
 2588: 	   []},
 2589:           %% but this doesn't mean the local function is allowed in a guard...
 2590: 	  {clash8,
 2591:            <<"-export([x/1]).
 2592:               -compile({no_auto_import,[binary_part/2]}).
 2593:               x(X) when binary_part(X,{1,2}) =:= <<1,2>> ->
 2594:                  hej.
 2595:               binary_part({B,_},{X,Y}) ->
 2596:                 binary_part(B,{X,Y});
 2597:               binary_part(B,{X,Y}) ->
 2598:                 binary:part(B,X,Y).
 2599:              ">>,
 2600: 	   [],
 2601: 	   {errors,[{3,erl_lint,{illegal_guard_local_call,{binary_part,2}}}],[]}},
 2602:           %% no_auto_import is not like nowarn_bif_clash, it actually removes the autoimport
 2603: 	  {clash9,
 2604:            <<"-export([x/1]).
 2605:               -compile({no_auto_import,[binary_part/2]}).
 2606:               x(X) ->
 2607:                  binary_part(X,{1,2}) =:= <<1,2>>.
 2608:              ">>,
 2609: 	   [],
 2610: 	   {errors,[{4,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
 2611:           %% but we could import it again...
 2612: 	  {clash10,
 2613:            <<"-export([x/1]).
 2614:               -compile({no_auto_import,[binary_part/2]}).
 2615:               -import(erlang,[binary_part/2]).
 2616:               x(X) ->
 2617:                  binary_part(X,{1,2}) =:= <<1,2>>.
 2618:              ">>,
 2619: 	   [],
 2620: 	   []},
 2621:           %% and actually use it in a guard...
 2622: 	  {clash11,
 2623:            <<"-export([x/1]).
 2624:               -compile({no_auto_import,[binary_part/2]}).
 2625:               -import(erlang,[binary_part/2]).
 2626:               x(X) when binary_part(X,{0,1}) =:= <<0>> ->
 2627:                  binary_part(X,{1,2}) =:= <<1,2>>.
 2628:              ">>,
 2629: 	   [],
 2630: 	   []},
 2631:           %% but for non-obvious historical reasons, imported functions cannot be used in
 2632: 	  %% fun construction without the module name...
 2633: 	  {clash12,
 2634:            <<"-export([x/1]).
 2635:               -compile({no_auto_import,[binary_part/2]}).
 2636:               -import(erlang,[binary_part/2]).
 2637:               x(X) when binary_part(X,{0,1}) =:= <<0>> ->
 2638:                  binary_part(X,{1,2}) =:= fun binary_part/2.
 2639:              ">>,
 2640: 	   [],
 2641: 	   {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
 2642:           %% Not from erlang and not from anywhere else
 2643: 	  {clash13,
 2644:            <<"-export([x/1]).
 2645:               -compile({no_auto_import,[binary_part/2]}).
 2646:               -import(x,[binary_part/2]).
 2647:               x(X) ->
 2648:                  binary_part(X,{1,2}) =:= fun binary_part/2.
 2649:              ">>,
 2650: 	   [],
 2651: 	   {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
 2652: 	  %% ...while real auto-import is OK.
 2653: 	  {clash14,
 2654:            <<"-export([x/1]).
 2655:               x(X) when binary_part(X,{0,1}) =:= <<0>> ->
 2656:                  binary_part(X,{1,2}) =:= fun binary_part/2.
 2657:              ">>,
 2658: 	   [],
 2659: 	   []},
 2660:           %% Import directive clashing with old bif is an error, regardless of if it's called or not
 2661: 	  {clash15,
 2662:            <<"-export([x/1]).
 2663:               -import(x,[abs/1]).
 2664:               x(X) ->
 2665:                  binary_part(X,{1,2}).
 2666:              ">>,
 2667: 	   [],
 2668: 	   {errors,[{2,erl_lint,{redefine_old_bif_import,{abs,1}}}],[]}},
 2669: 	  %% For a new BIF, it's only a warning
 2670: 	  {clash16,
 2671:            <<"-export([x/1]).
 2672:               -import(x,[binary_part/3]).
 2673:               x(X) ->
 2674:                  abs(X).
 2675:              ">>,
 2676: 	   [],
 2677: 	   {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}},
 2678: 	  %% And, you cannot redefine already imported things that aren't auto-imported
 2679: 	  {clash17,
 2680:            <<"-export([x/1]).
 2681:               -import(x,[binary_port/3]).
 2682:               -import(y,[binary_port/3]).
 2683:               x(X) ->
 2684:                  abs(X).
 2685:              ">>,
 2686: 	   [],
 2687: 	   {errors,[{3,erl_lint,{redefine_import,{{binary_port,3},x}}}],[]}},
 2688: 	  %% Not with local functions either
 2689: 	  {clash18,
 2690:            <<"-export([x/1]).
 2691:               -import(x,[binary_port/3]).
 2692:               binary_port(A,B,C) ->
 2693:                  binary_part(A,B,C).
 2694:               x(X) ->
 2695:                  abs(X).
 2696:              ">>,
 2697: 	   [],
 2698: 	   {errors,[{3,erl_lint,{define_import,{binary_port,3}}}],[]}},
 2699: 	  %% Like clash8: Dont accept a guard if it's explicitly module-name called either
 2700: 	  {clash19,
 2701:            <<"-export([binary_port/3]).
 2702:               -compile({no_auto_import,[binary_part/3]}).
 2703:               -import(x,[binary_part/3]).
 2704:               binary_port(A,B,C) when x:binary_part(A,B,C) ->
 2705:                  binary_part(A,B,C+1).
 2706:              ">>,
 2707: 	   [],
 2708: 	   {errors,[{4,erl_lint,illegal_guard_expr}],[]}},
 2709: 	  %% Not with local functions either
 2710: 	  {clash20,
 2711:            <<"-export([binary_port/3]).
 2712:               -import(x,[binary_part/3]).
 2713:               binary_port(A,B,C) ->
 2714:                  binary_part(A,B,C).
 2715:              ">>,
 2716: 	   [warn_unused_import],
 2717: 	   {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}},
 2718: 	  %% Don't accept call to a guard BIF if there is a local definition
 2719: 	  %% or an import with the same name. Note: is_record/2 is an
 2720: 	  %% exception, since it is more of syntatic sugar than a real BIF.
 2721: 	  {clash21,
 2722:            <<"-export([is_list/1]).
 2723:               -import(x, [is_tuple/1]).
 2724:               -record(r, {a,b}).
 2725:               x(T) when is_tuple(T) -> ok;
 2726:               x(T) when is_list(T) -> ok.
 2727:               y(T) when is_tuple(T) =:= true -> ok;
 2728:               y(T) when is_list(T) =:= true -> ok;
 2729:               y(T) when is_record(T, r, 3) -> ok;
 2730:               y(T) when is_record(T, r, 3) =:= true -> ok;
 2731:               y(T) when is_record(T, r) =:= true -> ok.
 2732:               is_list(_) ->
 2733:                 ok.
 2734:               is_record(_, _) ->
 2735:                 ok.
 2736:               is_record(_, _, _) ->
 2737:                 ok.
 2738:              ">>,
 2739: 	   [{no_auto_import,[{is_tuple,1}]}],
 2740: 	   {errors,[{4,erl_lint,{illegal_guard_local_call,{is_tuple,1}}},
 2741: 		    {5,erl_lint,{illegal_guard_local_call,{is_list,1}}},
 2742: 		    {6,erl_lint,{illegal_guard_local_call,{is_tuple,1}}},
 2743: 		    {7,erl_lint,{illegal_guard_local_call,{is_list,1}}},
 2744: 		    {8,erl_lint,{illegal_guard_local_call,{is_record,3}}},
 2745: 		    {9,erl_lint,{illegal_guard_local_call,{is_record,3}}}],[]}}
 2746: 	 ],
 2747: 
 2748:     ?line [] = run(Config, Ts),
 2749:     ok.
 2750: 
 2751: behaviour_basic(doc) ->
 2752:     "Basic tests with one behaviour.";
 2753: behaviour_basic(suite) -> [];
 2754: behaviour_basic(Config) when is_list(Config) ->
 2755:     Ts = [{behaviour1,
 2756:            <<"-behaviour(application).
 2757:              ">>,
 2758:            [],
 2759: 	   {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}},
 2760: 		      {1,erl_lint,{undefined_behaviour_func,{stop,1},application}}]}},
 2761: 
 2762: 	  {behaviour2,
 2763:            <<"-behaviour(application).
 2764:               -export([stop/1]).
 2765:               stop(_) -> ok.
 2766:              ">>,
 2767:            [],
 2768: 	   {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}}]}},
 2769: 	  
 2770: 	  {behaviour3,
 2771:            <<"-behavior(application).  %% Test American spelling.
 2772:               -export([start/2,stop/1]).
 2773:               start(_, _) -> ok.
 2774:               stop(_) -> ok.
 2775:              ">>,
 2776:            [],
 2777: 	   []}
 2778: 	 ],
 2779:     ?line [] = run(Config, Ts),
 2780:     ok.
 2781: 
 2782: behaviour_multiple(doc) ->
 2783:     "Basic tests with multiple behaviours.";
 2784: behaviour_multiple(suite) -> [];
 2785: behaviour_multiple(Config) when is_list(Config) ->
 2786:     Ts = [{behaviour1,
 2787:            <<"-behaviour(application).
 2788:               -behaviour(supervisor).
 2789:              ">>,
 2790:            [],
 2791: 	   {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}},
 2792: 		      {1,erl_lint,{undefined_behaviour_func,{stop,1},application}},
 2793: 		      {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}}]}},
 2794: 
 2795: 	  {behaviour2,
 2796:            <<"-behaviour(application).
 2797:               -behaviour(supervisor).
 2798:               -export([start/2,stop/1,init/1]).
 2799:               start(_, _) -> ok.
 2800:               stop(_) -> ok.
 2801:               init(_) -> ok.
 2802:              ">>,
 2803:            [],
 2804: 	   []},
 2805: 
 2806: 	  {american_behavior2,
 2807:            <<"-behavior(application).
 2808:               -behavior(supervisor).
 2809:               -export([start/2,stop/1,init/1]).
 2810:               start(_, _) -> ok.
 2811:               stop(_) -> ok.
 2812:               init(_) -> ok.
 2813:              ">>,
 2814:            [],
 2815: 	   []},
 2816: 
 2817: 	  {behaviour3,
 2818:            <<"-behaviour(gen_server).
 2819:               -behaviour(supervisor).
 2820:               -export([handle_call/3,handle_cast/2,handle_info/2]).
 2821:               handle_call(_, _, _) -> ok.
 2822:               handle_cast(_, _) -> ok.
 2823:               handle_info(_, _) -> ok.
 2824:              ">>,
 2825:            [],
 2826: 	   {warnings,[{1,erl_lint,
 2827: 		       {undefined_behaviour_func,{code_change,3},gen_server}},
 2828: 		      {1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
 2829: 		      {1,erl_lint,{undefined_behaviour_func,{terminate,2},gen_server}},
 2830: 		      {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}},
 2831: 		      {2,
 2832: 		       erl_lint,
 2833: 		       {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}},
 2834: 	  {american_behavior3,
 2835:            <<"-behavior(gen_server).
 2836:               -behavior(supervisor).
 2837:               -export([handle_call/3,handle_cast/2,handle_info/2]).
 2838:               handle_call(_, _, _) -> ok.
 2839:               handle_cast(_, _) -> ok.
 2840:               handle_info(_, _) -> ok.
 2841:              ">>,
 2842:            [],
 2843: 	   {warnings,[{1,erl_lint,
 2844: 		       {undefined_behaviour_func,{code_change,3},gen_server}},
 2845: 		      {1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
 2846: 		      {1,erl_lint,{undefined_behaviour_func,{terminate,2},gen_server}},
 2847: 		      {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}},
 2848: 		      {2,
 2849: 		       erl_lint,
 2850: 		       {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}},
 2851: 
 2852: 	  {behaviour4,
 2853:            <<"-behaviour(gen_server).
 2854:               -behaviour(gen_fsm).
 2855:               -behaviour(supervisor).
 2856:               -export([init/1,handle_call/3,handle_cast/2,
 2857:                        handle_info/2,handle_info/3,
 2858:                        handle_event/3,handle_sync_event/4,
 2859:                        code_change/3,code_change/4,
 2860:                        terminate/2,terminate/3,terminate/4]).
 2861:               init(_) -> ok.
 2862:               handle_call(_, _, _) -> ok.
 2863:               handle_event(_, _, _) -> ok.
 2864:               handle_sync_event(_, _, _, _) -> ok.
 2865:               handle_cast(_, _) -> ok.
 2866:               handle_info(_, _) -> ok.
 2867:               handle_info(_, _, _) -> ok.
 2868:               code_change(_, _, _) -> ok.
 2869:               code_change(_, _, _, _) -> ok.
 2870:               terminate(_, _) -> ok.
 2871:               terminate(_, _, _) -> ok.
 2872:               terminate(_, _, _, _) -> ok.
 2873:              ">>,
 2874:            [],
 2875: 	   {warnings,[{2,
 2876: 		       erl_lint,
 2877: 		       {conflicting_behaviours,{init,1},gen_fsm,1,gen_server}},
 2878: 		      {3,
 2879: 		       erl_lint,
 2880: 		       {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}}
 2881: 	 ],
 2882:     ?line [] = run(Config, Ts),
 2883:     ok.
 2884: 
 2885: otp_7550(doc) ->
 2886:     "Test that the new utf8/utf16/utf32 types do not allow size or unit specifiers.";
 2887: otp_7550(Config) when is_list(Config) ->
 2888:     Ts = [{otp_7550,
 2889:            <<"f8(A) ->
 2890:                   <<A:8/utf8>>.
 2891:               g8(A) ->
 2892:                   <<A:8/utf8-unit:1>>.
 2893:               h8(A) ->
 2894:                   <<A/utf8-unit:1>>.
 2895: 
 2896:               f16(A) ->
 2897:                   <<A:8/utf16>>.
 2898:               g16(A) ->
 2899:                   <<A:8/utf16-unit:1>>.
 2900:               h16(A) ->
 2901:                   <<A/utf16-unit:1>>.
 2902: 
 2903:               f32(A) ->
 2904:                   <<A:8/utf32>>.
 2905:               g32(A) ->
 2906:                   <<A:8/utf32-unit:1>>.
 2907:               h32(A) ->
 2908:                   <<A/utf32-unit:1>>.
 2909:              ">>,
 2910:            [],
 2911:            {errors,[{2,erl_lint,utf_bittype_size_or_unit},
 2912: 		    {4,erl_lint,utf_bittype_size_or_unit},
 2913: 		    {6,erl_lint,utf_bittype_size_or_unit},
 2914: 		    {9,erl_lint,utf_bittype_size_or_unit},
 2915: 		    {11,erl_lint,utf_bittype_size_or_unit},
 2916: 		    {13,erl_lint,utf_bittype_size_or_unit},
 2917: 		    {16,erl_lint,utf_bittype_size_or_unit},
 2918: 		    {18,erl_lint,utf_bittype_size_or_unit},
 2919: 		    {20,erl_lint,utf_bittype_size_or_unit}
 2920: 		   ],
 2921:             []}}],
 2922:     ?line [] = run(Config, Ts),
 2923:     ok.
 2924:     
 2925: 
 2926: otp_8051(doc) ->
 2927:     "Bugfix: -opaque with invalid type.";
 2928: otp_8051(Config) when is_list(Config) ->
 2929:     Ts = [{otp_8051,
 2930:            <<"-opaque foo() :: bar().
 2931:               -export_type([foo/0]).
 2932:              ">>,
 2933:            [],
 2934:            {errors,[{1,erl_lint,{undefined_type,{bar,0}}}],[]}}],
 2935:     ?line [] = run(Config, Ts),
 2936:     ok.
 2937: 
 2938: format_warn(doc) ->
 2939:     "Check that format warnings are generated.";
 2940: format_warn(suite) -> [];
 2941: format_warn(Config) when is_list(Config) ->
 2942:     L1 = 14,
 2943:     L2 = 4,
 2944:     format_level(1, L1, Config),
 2945:     format_level(2, L1+L2, Config),
 2946:     format_level(3, L1+L2, Config),             %there is no level 3
 2947:     ok.
 2948: 
 2949: format_level(Level, Count, Config) ->
 2950:     ?line W = get_compilation_warnings(Config, "format",
 2951:                                        [{warn_format, Level}]),
 2952:     %% Pick out the 'format' warnings.
 2953:     ?line FW = lists:filter(fun({_Line, erl_lint, {format_error, _}}) -> true;
 2954:                                (_) -> false
 2955:                             end,
 2956:                             W),
 2957:     ?line case length(FW) of
 2958:               Count ->
 2959:                   ok;
 2960:               Other ->
 2961:                   ?t:format("Expected ~w warning(s); got ~w", [Count,Other]),
 2962:                   fail()
 2963:           end,
 2964:     ok.
 2965: 
 2966: %% Test the -on_load(Name/0) directive.
 2967: 
 2968: 
 2969: on_load_successful(Config) when is_list(Config) ->
 2970:     Ts = [{on_load_1,
 2971: 	   %% Exported on_load function.
 2972: 	   <<"-export([do_on_load/0]).
 2973:              -on_load(do_on_load/0).
 2974:              do_on_load() -> ok.
 2975:              ">>,
 2976: 	   {[]},				%Tuple indicates no 'export_all'.
 2977: 	   []},
 2978: 
 2979: 	  {on_load_2,
 2980: 	   %% Local on_load function.
 2981: 	   <<"-on_load(do_on_load/0).
 2982:              do_on_load() -> ok.
 2983:              ">>,
 2984: 	   {[]},				%Tuple indicates no 'export_all'.
 2985: 	   []},
 2986: 
 2987: 	  {on_load_3,
 2988: 	   %% Local on_load function, calling other local functions.
 2989: 	   <<"-on_load(do_on_load/0).
 2990:              do_on_load() -> foo().
 2991:              foo() -> bar(5) + 42.
 2992:              bar(N) -> 2*N.
 2993:              ">>,
 2994: 	   {[]},				%Tuple indicates no 'export_all'.
 2995: 	   []}
 2996: 	 ],
 2997:     ?line [] = run(Config, Ts),
 2998:     ok.
 2999: 
 3000: on_load_failing(Config) when is_list(Config) ->
 3001:     Ts = [{on_load_1,
 3002: 	   %% Badly formed.
 3003: 	   <<"-on_load(atom).
 3004:              ">>,
 3005: 	   {[]},				%Tuple indicates no 'export_all'.
 3006: 	   {errors,
 3007: 	    [{1,erl_lint,{bad_on_load,atom}}],[]}},
 3008: 
 3009: 	  {on_load_2,
 3010: 	   %% Badly formed.
 3011: 	   <<"-on_load({42,0}).
 3012:              ">>,
 3013: 	   {[]},				%Tuple indicates no 'export_all'.
 3014: 	   {errors,
 3015: 	    [{1,erl_lint,{bad_on_load,{42,0}}}],[]}},
 3016: 
 3017: 	  {on_load_3,
 3018: 	   %% Multiple on_load attributes.
 3019: 	   <<"-on_load(foo/0).
 3020:               -on_load(bar/0).
 3021:               foo() -> ok.
 3022:               bar() -> ok.
 3023:              ">>,
 3024: 	   {[]},				%Tuple indicates no 'export_all'.
 3025: 	   {errors,
 3026: 	    [{2,erl_lint,multiple_on_loads}],[]}},
 3027: 
 3028: 	  {on_load_4,
 3029: 	   %% Wrong arity.
 3030: 	   <<"-on_load(foo/1).
 3031:               foo(_) -> ok.
 3032:              ">>,
 3033: 	   {[]},				%Tuple indicates no 'export_all'.
 3034: 	   {errors,
 3035: 	    [{1,erl_lint,{bad_on_load_arity,{foo,1}}}],[]}},
 3036: 
 3037: 	  {on_load_5,
 3038: 	   %% Non-existing function.
 3039: 	   <<"-on_load(non_existing/0).
 3040:              ">>,
 3041: 	   {[]},				%Tuple indicates no 'export_all'.
 3042: 	   {errors,
 3043: 	    [{1,erl_lint,{undefined_on_load,{non_existing,0}}}],[]}}
 3044: 	 ],
 3045:     ?line [] = run(Config, Ts),
 3046:     ok.
 3047: 
 3048: too_many_arguments(doc) ->
 3049:     "Test that too many arguments is not accepted.";
 3050: too_many_arguments(suite) -> [];
 3051: too_many_arguments(Config) when is_list(Config) ->
 3052:     Ts = [{too_many_1,
 3053: 	   <<"f(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ok.">>,
 3054: 	   [],
 3055: 	   {errors,
 3056: 	    [{1,erl_lint,{too_many_arguments,256}}],[]}}
 3057: 	 ],
 3058: 	  
 3059:     ?line [] = run(Config, Ts),
 3060:     ok.
 3061: 
 3062: 
 3063: %% Test some basic errors to improve coverage.
 3064: basic_errors(Config) ->
 3065:     Ts = [{redefine_module,
 3066: 	   <<"-module(redefine_module).">>,
 3067: 	   [],
 3068: 	   {errors,[{1,erl_lint,redefine_module}],[]}},
 3069: 
 3070: 	  {attr_after_function,
 3071: 	   <<"f() -> ok.
 3072:                -attr(x).">>,
 3073: 	   [],
 3074: 	   {errors,[{2,erl_lint,{attribute,attr}}],[]}},
 3075: 
 3076: 	  {redefine_function,
 3077: 	   <<"f() -> ok.
 3078:               f() -> ok.">>,
 3079: 	   [],
 3080: 	   {errors,[{2,erl_lint,{redefine_function,{f,0}}}],[]}},
 3081: 
 3082: 	  {redefine_record,
 3083: 	   <<"-record(r, {a}).
 3084:               -record(r, {a}).
 3085: 	      f(#r{}) -> ok.">>,
 3086: 	   [],
 3087: 	   {errors,[{2,erl_lint,{redefine_record,r}}],[]}},
 3088: 
 3089: 	  {illegal_record_info,
 3090: 	   <<"f1() -> record_info(42, record).
 3091: 	      f2() -> record_info(shoe_size, record).">>,
 3092: 	   [],
 3093: 	   {errors,[{1,erl_lint,illegal_record_info},
 3094: 		    {2,erl_lint,illegal_record_info}],[]}},
 3095: 
 3096: 	  {illegal_expr,
 3097: 	   <<"f() -> a:b.">>,
 3098: 	   [],
 3099: 	   {errors,[{1,erl_lint,illegal_expr}],[]}},
 3100: 
 3101: 	  {illegal_pattern,
 3102: 	   <<"f(A+B) -> ok.">>,
 3103: 	   [],
 3104: 	   {errors,[{1,erl_lint,illegal_pattern}],[]}}
 3105: 	 ],
 3106:     [] = run(Config, Ts),
 3107:     ok.
 3108: 
 3109: %% Test binary syntax errors
 3110: bin_syntax_errors(Config) ->
 3111:     Ts = [{bin_syntax_errors,
 3112: 	   <<"t(<<X:bad_size>>) -> X;
 3113: 	      t(<<_:(x ! y)/integer>>) -> ok;
 3114:               t(<<X:all/integer>>) -> X;
 3115:               t(<<X/bad_type>>) -> X;
 3116: 	      t(<<X/unit:8>>) -> X;
 3117: 	      t(<<X:7/float>>) -> X;
 3118: 	      t(<< <<_:8>> >>) -> ok;
 3119: 	      t(<<(x ! y):8/integer>>) -> ok.
 3120: 	    ">>,
 3121: 	   [],
 3122: 	   {error,[{1,erl_lint,illegal_bitsize},
 3123: 		   {2,erl_lint,illegal_bitsize},
 3124: 		   {3,erl_lint,illegal_bitsize},
 3125: 		   {4,erl_lint,{undefined_bittype,bad_type}},
 3126: 		   {5,erl_lint,bittype_unit},
 3127: 		   {7,erl_lint,illegal_pattern},
 3128: 		   {8,erl_lint,illegal_pattern}],
 3129: 	    [{6,erl_lint,{bad_bitsize,"float"}}]}}
 3130: 	 ],
 3131:     [] = run(Config, Ts),
 3132:     ok.
 3133: 
 3134: run(Config, Tests) ->
 3135:     F = fun({N,P,Ws,E}, BadL) ->
 3136:                 case catch run_test(Config, P, Ws) of
 3137:                     E -> 
 3138:                         BadL;
 3139:                     Bad -> 
 3140:                         ?t:format("~nTest ~p failed. Expected~n  ~p~n"
 3141:                                   "but got~n  ~p~n", [N, E, Bad]),
 3142: 			fail()
 3143:                 end
 3144:         end,
 3145:     lists:foldl(F, [], Tests).
 3146: 
 3147: %% Compiles a test file and returns the list of warnings.
 3148: 
 3149: get_compilation_warnings(Conf, Filename, Warnings) ->
 3150:     ?line DataDir = ?datadir,
 3151:     ?line File = filename:join(DataDir, Filename),
 3152:     {ok,Bin} = file:read_file(File++".erl"),
 3153:     FileS = binary_to_list(Bin),
 3154:     {match,[{Start,Length}|_]} = re:run(FileS, "-module.*\\n"),
 3155:     Test = lists:nthtail(Start+Length, FileS),
 3156:     {warnings, Ws} = run_test(Conf, Test, Warnings),
 3157:     Ws.
 3158: 
 3159: %% Compiles a test module and returns the list of errors and warnings.
 3160: 
 3161: run_test(Conf, Test0, Warnings0) ->
 3162:     Test = list_to_binary(["-module(lint_test). ", Test0]),
 3163:     run_test2(Conf, Test, Warnings0).
 3164: 
 3165: run_test2(Conf, Test, Warnings0) ->
 3166:     Filename = "lint_test.erl",
 3167:     DataDir = ?privdir,
 3168:     File = filename:join(DataDir, Filename),
 3169:     Opts = case Warnings0 of
 3170:                {Warnings} ->		%Hairy trick to not add export_all.
 3171:                    [return|Warnings];
 3172:                Warnings ->
 3173:                    [export_all,return|Warnings]
 3174:            end,
 3175:     ok = file:write_file(File, Test),
 3176: 
 3177:     %% We will use the 'binary' option so that the compiler will not
 3178:     %% compare the module name to the output file name. Also, there
 3179:     %% is no reason to produce an output file since we are only
 3180:     %% interested in the errors and warnings.
 3181: 
 3182:     %% Print warnings, call erl_lint:format_error/1.
 3183:     compile:file(File, [binary,report|Opts]),
 3184: 
 3185:     case compile:file(File, [binary|Opts]) of
 3186:         {ok, _M, Code, Ws} when is_binary(Code) -> warnings(File, Ws);
 3187:         {error, [{File,Es}], []} -> {errors, Es, []};
 3188:         {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws};
 3189:         {error, [{File,Es1},{File,Es2}], []} -> {errors2, Es1, Es2}
 3190:     end.
 3191: 
 3192: warnings(File, Ws) ->
 3193:     case lists:append([W || {F, W} <- Ws, F =:= File]) of
 3194:         [] -> [];
 3195:         L -> {warnings, L}
 3196:     end.
 3197: 
 3198: fail() ->
 3199:     io:format("failed~n"),
 3200:     ?t:fail().