PageRenderTime 170ms CodeModel.GetById 3ms app.highlight 153ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/compiler/test/guard_SUITE.erl

https://github.com/bsmr-erlang/otp
Erlang | 2277 lines | 1761 code | 393 blank | 123 comment | 212 complexity | 03a13aa4038ad066497dd8c8125137f1 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1%%
   2%% %CopyrightBegin%
   3%%
   4%% Copyright Ericsson AB 2001-2018. All Rights Reserved.
   5%%
   6%% Licensed under the Apache License, Version 2.0 (the "License");
   7%% you may not use this file except in compliance with the License.
   8%% You may obtain a copy of the License at
   9%%
  10%%     http://www.apache.org/licenses/LICENSE-2.0
  11%%
  12%% Unless required by applicable law or agreed to in writing, software
  13%% distributed under the License is distributed on an "AS IS" BASIS,
  14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15%% See the License for the specific language governing permissions and
  16%% limitations under the License.
  17%%
  18%% %CopyrightEnd%
  19%%
  20-module(guard_SUITE).
  21
  22-include_lib("common_test/include/ct.hrl").
  23
  24-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
  25	 init_per_group/2,end_per_group/2,
  26	 misc/1,const_cond/1,basic_not/1,complex_not/1,nested_nots/1,
  27	 semicolon/1,complex_semicolon/1,comma/1,
  28	 or_guard/1,more_or_guards/1,
  29	 complex_or_guards/1,and_guard/1,
  30	 xor_guard/1,more_xor_guards/1,
  31	 old_guard_tests/1,complex_guard/1,
  32	 build_in_guard/1,gbif/1,
  33	 t_is_boolean/1,is_function_2/1,
  34	 tricky/1,rel_ops/1,rel_op_combinations/1,literal_type_tests/1,
  35	 basic_andalso_orelse/1,traverse_dcd/1,
  36	 check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
  37	 bad_constants/1,bad_guards/1,
  38         guard_in_catch/1,beam_bool_SUITE/1]).
  39
  40suite() -> [{ct_hooks,[ts_install_cth]}].
  41
  42all() -> 
  43    [{group,p}].
  44
  45groups() -> 
  46    [{p,[parallel],
  47      [misc,const_cond,basic_not,complex_not,nested_nots,
  48       semicolon,complex_semicolon,comma,or_guard,
  49       more_or_guards,complex_or_guards,and_guard,xor_guard,
  50       more_xor_guards,build_in_guard,
  51       old_guard_tests,complex_guard,gbif,
  52       t_is_boolean,is_function_2,tricky,
  53       rel_ops,rel_op_combinations,
  54       literal_type_tests,basic_andalso_orelse,traverse_dcd,
  55       check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
  56       bad_constants,bad_guards,guard_in_catch,beam_bool_SUITE]}].
  57
  58init_per_suite(Config) ->
  59    test_lib:recompile(?MODULE),
  60    Config.
  61
  62end_per_suite(_Config) ->
  63    ok.
  64
  65init_per_group(_GroupName, Config) ->
  66    Config.
  67
  68end_per_group(_GroupName, Config) ->
  69    Config.
  70
  71
  72misc(Config) when is_list(Config) ->
  73    42 = case id(42) of
  74	     X when -X -> ok;
  75	     X -> X
  76	 end,
  77    {a,b,c} = misc_1([{{a,b,c}},{[4]},{[3]},{-2}]),
  78    none = misc_1([{{a,b,c}},{[4]},{[3]},{-3}]),
  79    none = misc_1([{{a,b,c}},{[4]},{[7]},{-2}]),
  80    none = misc_1([{{a,b,c}},{[4]},{[3]},{[1,2,3]}]),
  81
  82    {ok,buf,<<>>} = get_data({o,true,raw}, 0, buf),
  83    {ok,buf,<<>>} = get_data({o,true,raw}, 42, buf),
  84    {ok,buf,<<>>} = get_data({o,false,raw}, 0, buf),
  85    error = get_data({o,false,raw}, 42, buf),
  86    {ok,buf,<<>>} = get_data({o,true,0}, 0, buf),
  87    {ok,buf,<<>>} = get_data({o,true,0}, 42, buf),
  88    {ok,buf,<<>>} = get_data({o,false,0}, 0, buf),
  89    error = get_data({o,false,0}, 42, buf),
  90
  91    relief = misc_2(0),
  92    error = misc_2(1),
  93    error = misc_2(true),
  94
  95    if
  96	is_integer(Config) =/= true ->
  97	    ok
  98    end,
  99
 100    true = misc_3(1, 0),
 101    true = misc_3(0, 0),
 102    false = misc_3(0, 2),
 103
 104    %% Abuse of boolean values.
 105
 106    Zero = id(0),
 107    One = id(1),
 108    ok = if (Zero == 0) > false -> ok end,
 109    ok = if (Zero == 0) =:= (One == 1) -> ok end,
 110    ok = if (Zero == 0) =:= (One == 1) -> ok end,
 111    ok = if is_atom(Zero > One) -> ok end,
 112    error = if abs(Zero > One) -> ok; true -> error end,
 113    ok = if is_integer(Zero) >= is_integer(One) -> ok end,
 114
 115    ok.
 116
 117misc_1([{W},{X},{Y},{Z}]) ->
 118	      if
 119	X > Y andalso abs(Z) =:= 2 ->
 120	    id(W);
 121	true ->
 122	    none
 123    end.
 124
 125misc_2(0) -> relief;
 126misc_2(Adapter = 1) when Adapter -> franklin;
 127misc_2(_) -> error.
 128
 129misc_3(LenUp, LenDw) ->
 130    if
 131	%% Cover handling of #k_alt{}.
 132	LenUp >= 1 orelse ((LenDw >= 2) xor true) -> true;
 133	true -> false
 134    end.
 135
 136get_data({o,Active,Raw}, BytesToRead, Buffer) 
 137  when Raw =:= raw; Raw =:= 0 ->
 138    if 
 139	Active =/= false orelse BytesToRead =:= 0  ->
 140	    {ok,Buffer,<<>>};
 141	true ->
 142	    error
 143    end.
 144
 145const_cond(Config) when is_list(Config) ->
 146    ok = const_cond({}, 0),
 147    ok = const_cond({a}, 1),
 148    error = const_cond({a,b}, 3),
 149    error = const_cond({a}, 0),
 150    error = const_cond({a,b}, 1),
 151    ok.
 152
 153const_cond(T, Sz) ->
 154    case T of
 155	_X when false -> never;
 156	_X when is_tuple(T), eq == eq, tuple_size(T) == Sz -> ok;
 157	_X when is_tuple(T), eq == leq, tuple_size(T) =< Sz -> ok;
 158	_X -> error
 159    end.
 160
 161basic_not(Config) when is_list(Config) ->
 162    True = id(true),
 163    False = id(false),
 164    Glurf = id(glurf),
 165    A = id(5),
 166    B = id(37.5),
 167    C = id(-1),
 168    D = id(5),
 169    ATuple = {False,True,Glurf},
 170
 171    check(fun() -> if not false -> ok; true -> error end end, ok),
 172    check(fun() -> if not true -> ok; true -> error end end, error),
 173    check(fun() -> if not False -> ok; true -> error end end, ok),
 174    check(fun() -> if not True -> ok; true -> error end end, error),
 175
 176    check(fun() -> if A > B -> gt; A < B -> lt; A == B -> eq end end, lt),
 177    check(fun() -> if A > C -> gt; A < C -> lt; A == C -> eq end end, gt),
 178    check(fun() -> if A > D -> gt; A < D -> lt; A == D -> eq end end, eq),
 179
 180    check(fun() -> if not (7 > 453) -> le; not (7 < 453) -> ge;
 181		      not (7 == 453) -> ne; true -> eq end end, le),
 182    check(fun() -> if not (7 > -8) -> le; not (7 < -8) -> ge;
 183		      not (7 == -8) -> ne; true -> eq end end, ge),
 184    check(fun() -> if not (7 > 7) -> le; not (7 < 7) -> ge;
 185		      not (7 == 7) -> ne; true -> eq end end, le),
 186
 187    check(fun() -> if not (A > B) -> le; not (A < B) -> ge;
 188		      not (A == B) -> ne; true -> eq end end, le),
 189    check(fun() -> if not (A > C) -> le; not (A < C) -> ge;
 190		      not (A == C) -> ne; true -> eq end end, ge),
 191    check(fun() -> if not (A > D) -> le; not (A < D) -> ge;
 192		      not (A == D) -> ne; true -> eq end end, le),
 193
 194    check(fun() -> if not element(1, ATuple) -> ok; true -> error end end, ok),
 195    check(fun() -> if not element(2, ATuple) -> ok; true -> error end end, error),
 196    check(fun() -> if not element(3, ATuple) -> ok; true -> error end end, error),
 197
 198    check(fun() -> if not glurf -> ok; true -> error end end, error),
 199    check(fun() -> if not Glurf -> ok; true -> error end end, error),
 200
 201    check(fun() -> if not (not true) -> broken end end, broken),
 202
 203    check(fun() -> if not (True xor True) -> ok end end, ok),
 204    check(fun() -> if not (True xor False) -> ok;
 205		      true -> error end end, error),
 206
 207    ok.
 208
 209complex_not(Config) when is_list(Config) ->
 210    ATuple = id({false,true,gurka}),
 211    check(fun() -> if not(element(1, ATuple)) -> ok; true -> error end end, ok),
 212    check(fun() -> if not(element(2, ATuple)) -> ok; true -> error end end, error),
 213
 214    check(fun() -> if not(element(3, ATuple) == gurka) -> ok;
 215		      true -> error end end, error),
 216    check(fun() -> if not(element(3, ATuple) =/= gurka) -> ok;
 217		      true -> error end end, ok),
 218
 219    check(fun() -> if {a,not(element(2, ATuple))} == {a,false} -> ok;
 220		      true -> error end end, ok),
 221    check(fun() -> if {a,not(element(1, ATuple))} == {a,false} -> ok;
 222		      true -> error end end, error),
 223
 224    check(fun() -> if not(element(1, ATuple) or element(3, ATuple)) -> ok;
 225		      true -> error end end, error),
 226
 227    %% orelse
 228    check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok;
 229		      true -> error end end, error),
 230
 231    %% complex_not_1/4
 232    ok = complex_not_1(1, 1, 1, a),
 233    error = complex_not_1(1, 1, 1, []),
 234    error = complex_not_1(1, 1, 3, a),
 235    error = complex_not_1(1, 1, 3, []),
 236    error = complex_not_1(1, 2, 1, a),
 237    error = complex_not_1(1, 2, 1, []),
 238    error = complex_not_1(1, 2, 3, a),
 239    error = complex_not_1(1, 2, 3, []),
 240
 241    %% complex_not_2/4
 242    ok = complex_not_2(1, 2, 0, x),
 243    error = complex_not_2(1, 2, 0, []),
 244    error = complex_not_2(1, 2, 3, x),
 245    error = complex_not_2(1, 2, 3, []),
 246    error = complex_not_2(1, 1, 0, x),
 247    error = complex_not_2(1, 1, 0, []),
 248    error = complex_not_2(1, 1, 3, x),
 249    error = complex_not_2(1, 1, 3, []),
 250
 251    ok.
 252
 253complex_not_1(A, B, C, D) ->
 254    Res = complex_not_1a(A, B, C, D),
 255    Res = complex_not_1b(A, B, C, D).
 256
 257complex_not_1a(A, B, C, D)
 258  when (not (A < B)) andalso (not (B < C)) andalso (not is_list(D)) ->
 259    ok;
 260complex_not_1a(_, _, _, _) ->
 261    error.
 262
 263complex_not_1b(A, B, C, D)
 264  when (not (A < B)) and (not (B < C)) and (not is_list(D)) ->
 265    ok;
 266complex_not_1b(_, _, _, _) ->
 267    error.
 268
 269complex_not_2(A, B, C, D) ->
 270    Res = complex_not_2a(A, B, C, D),
 271    Res = complex_not_2b(A, B, C, D).
 272
 273complex_not_2a(A, B, C, D)
 274  when A < B andalso not (B < C) andalso not is_list(D) ->
 275    ok;
 276complex_not_2a(_, _, _, _) ->
 277    error.
 278
 279complex_not_2b(A, B, C, D)
 280  when A < B, not (B < C), not is_list(D) ->
 281    ok;
 282complex_not_2b(_, _, _, _) ->
 283    error.
 284
 285nested_nots(Config) when is_list(Config) ->
 286    true = nested_not_1(0, 0),
 287    true = nested_not_1(0, 1),
 288    true = nested_not_1(a, b),
 289    true = nested_not_1(10, 0),
 290    false = nested_not_1(z, a),
 291    false = nested_not_1(3.4, {anything,goes}),
 292    false = nested_not_1(3.4, atom),
 293    true = nested_not_1(3.0, [list]),
 294
 295    true = nested_not_2(false, false, 42),
 296    true = nested_not_2(false, true, 42),
 297    true = nested_not_2(true, false, 42),
 298    true = nested_not_2(true, true, 42),
 299    true = nested_not_2(false, false, atom),
 300    false = nested_not_2(false, true, atom),
 301    false = nested_not_2(true, false, atom),
 302    false = nested_not_2(true, true, atom),
 303    ok.
 304
 305nested_not_1(X, Y) ->
 306    Res = nested_not_1a(X, Y),
 307    Res = nested_not_1b(X, Y).
 308
 309nested_not_1a(X, Y) when not (((X>Y) or not(is_atom(X))) and
 310			     (is_atom(Y) or (X==3.4))) ->
 311    true;
 312nested_not_1a(_, _) ->
 313    false.
 314
 315nested_not_1b(X, Y) when not (((X>Y) orelse not(is_atom(X))) andalso
 316			     (is_atom(Y) orelse (X==3.4))) ->
 317    true;
 318nested_not_1b(_, _) ->
 319    false.
 320
 321nested_not_2(X, Y, Z) ->
 322    Res = nested_not_2a(X, Y, Z, true),
 323    Res = nested_not_2b(X, Y, Z, true).
 324
 325nested_not_2a(X, Y, Z, True)
 326  when not(True and not((not(X) and not(Y)) or not(is_atom(Z)))) ->
 327    true;
 328nested_not_2a(_, _, _, _) ->
 329    false.
 330
 331nested_not_2b(X, Y, Z, True)
 332  when not(True andalso not((not(X) andalso not(Y)) orelse not(is_atom(Z)))) ->
 333    true;
 334nested_not_2b(_, _, _, _) ->
 335    false.
 336
 337semicolon(Config) when is_list(Config) ->
 338
 339    %% True/false combined using ';' (literal atoms).
 340
 341    check(fun() -> if true; false -> ok end end, ok),
 342    check(fun() -> if false; true -> ok end end, ok),
 343    check(fun() -> if true; true -> ok end end, ok),
 344    check(fun() -> if false; false -> ok; true -> error end end, error),
 345    check(fun() ->
 346		  {'EXIT',{if_clause,_}} = (catch if false; false -> ok end),
 347		  exit
 348	  end, exit),
 349
 350    %% True/false combined used ';'.
 351
 352    True = id(true),
 353    False = id(false),
 354
 355    check(fun() -> if True; False -> ok end end, ok),
 356    check(fun() -> if False; True -> ok end end, ok),
 357    check(fun() -> if True; True -> ok end end, ok),
 358    check(fun() -> if False; False -> ok; true -> error end end, error),
 359    check(fun() ->
 360		  {'EXIT',{if_clause,_}} = (catch if False; False -> ok end),
 361		  exit
 362	  end, exit),
 363
 364    %% Combine true/false with a non-boolean value.
 365    Glurf = id(glurf),
 366
 367
 368    check(fun() -> if True; Glurf -> ok end end, ok),
 369    check(fun() -> if Glurf; True -> ok end end, ok),
 370    check(fun() -> if Glurf; Glurf -> ok; true -> error end end, error),
 371    check(fun() -> if False; Glurf -> ok; true -> error end end, error),
 372    check(fun() -> if Glurf; False -> ok; true -> error end end, error),
 373    check(fun() ->
 374		  {'EXIT',{if_clause,_}} = (catch if Glurf; Glurf -> ok end),
 375		  exit
 376	  end, exit),
 377
 378    %% Combine true/false with errors.
 379
 380    ATuple = id({false,true,gurka}),
 381
 382    check(fun() -> if True; element(42, ATuple) -> ok end end, ok),
 383    check(fun() -> if element(42, ATuple); True -> ok end end, ok),
 384    check(fun() -> if element(42, ATuple); element(42, ATuple) -> ok;
 385		      true -> error end end, error),
 386    check(fun() -> if False; element(42, ATuple) -> ok;
 387		      true -> error end end, error),
 388    check(fun() -> if element(42, ATuple);
 389		      False -> ok; true -> error end end, error),
 390    check(fun() ->
 391		  {'EXIT',{if_clause,_}} =
 392		      (catch if element(42, ATuple);
 393				element(42, ATuple) -> ok end),
 394		  exit
 395	  end, exit),
 396
 397    ok.
 398
 399complex_semicolon(Config) when is_list(Config) ->
 400    ok = csemi1(int, {blurf}),
 401    ok = csemi1(string, {blurf}),
 402    ok = csemi1(float, [a]),
 403    error = csemi1(35, 42),
 404
 405    %% 2
 406    ok = csemi2({}, {a,b,c}),
 407    ok = csemi2({1,3.5}, {a,b,c}),
 408    ok = csemi2(dum, {a,b,c}),
 409
 410    ok = csemi2({45,-19.3}, {}),
 411    ok = csemi2({45,-19.3}, {dum}),
 412    ok = csemi2({45,-19.3}, {dum,dum}),
 413
 414    error = csemi2({45}, {dum}),
 415    error = csemi2([], {dum}),
 416    error = csemi2({dum}, []),
 417    error = csemi2([], []),
 418
 419    %% 3
 420    csemi3(fun csemi3a/4),
 421    csemi3(fun csemi3b/4),
 422    csemi3(fun csemi3c/4),
 423
 424    %% 4
 425    csemi4(fun csemi4a/4),
 426    csemi4(fun csemi4b/4),
 427    csemi4(fun csemi4c/4),
 428    csemi4(fun csemi4d/4),
 429
 430    %% 4, 'orelse' instead of 'or'
 431    csemi4_orelse(fun csemi4_orelse_a/4),
 432    csemi4_orelse(fun csemi4_orelse_b/4),
 433    csemi4_orelse(fun csemi4_orelse_c/4),
 434    csemi4_orelse(fun csemi4_orelse_d/4),
 435
 436    %% 5
 437    error = csemi5(0, 0),
 438    ok = csemi5(5, 0),
 439    ok = csemi5(4, -4),
 440    ok = csemi5(10, -4),
 441
 442    %% 6
 443    error = csemi6({a}, 0),
 444    ok = csemi6({a,b}, 0),
 445    ok = csemi6({}, 3),
 446    ok = csemi6({a,b,c}, 3),
 447
 448    %% 7
 449    error = csemi7(#{a=>1}, 1, 0),
 450    error = csemi7(<<>>, 1, 0),
 451    ok = csemi7(#{a=>1}, 3, 0),
 452    ok = csemi7(#{a=>1}, 0, 3),
 453    ok = csemi7(#{a=>1}, 3, 3),
 454    ok = csemi7(#{a=>1, b=>3}, 0, 0),
 455
 456    %% 8: Make sure that funs cannot be copied into guards.
 457    ok = csemi8(true),
 458    error = csemi8(false),
 459    error = csemi8(42),
 460
 461    ok.
 462
 463csemi1(Type, Val) when is_list(Val), Type == float;
 464		       Type == int; Type == string -> ok;
 465csemi1(_, _) -> error.
 466
 467csemi2(A, B) when tuple_size(A) > 1; tuple_size(B) > 2 -> ok;
 468csemi2(_, _) -> error.
 469
 470csemi3(Csemi3) ->
 471    ok = Csemi3({}, {a,b,c}, [0], [0]),
 472    ok = Csemi3({1,3.5}, {a,b,c}, -1, -1),
 473    ok = Csemi3(dum, {a,b,c}, 0.0, 0.0),
 474    ok = Csemi3(dum, {c}, b, a),
 475    ok = Csemi3(dum, <<1,2,3>>, 0.0, 0.0),
 476    ok = Csemi3(<<3.5/float>>, {a,b,c}, -1, -1),
 477
 478    ok = Csemi3({45,-19.3}, {}, [], []),
 479    ok = Csemi3({45,-19.3}, {dum}, 42, 42),
 480    ok = Csemi3({45,-19.3}, {dum,dum}, 33, 33),
 481
 482    ok = Csemi3({45}, {dum}, 1.0, 0),
 483    ok = Csemi3([a], {dum}, 1.0, 0),
 484    ok = Csemi3({dum}, [], 1.0, 0),
 485    ok = Csemi3([], [], 1.0, 0),
 486    ok = Csemi3(blurf, {dum}, 1.0, 0),
 487    ok = Csemi3({a}, blurf, 1.0, 0),
 488    ok = Csemi3([a], [dum], 1.0, 0),
 489    ok = Csemi3({dum}, [], 1.0, 0),
 490    ok = Csemi3([], [], 1.0, 0),
 491
 492    error = Csemi3({45}, {dum}, 0, 0),
 493    error = Csemi3([a], {dum}, 0, 0),
 494    error = Csemi3({dum}, [], 0, 0),
 495    error = Csemi3([], [], 0, 0),
 496
 497    ok.
 498
 499csemi3a(A, B, X, Y) when X > Y; size(A) > 1; size(B) > 2 -> ok;
 500csemi3a(_, _, _, _) -> error.
 501
 502csemi3b(A, B, X, Y) when size(A) > 1; X > Y; size(B) > 2 -> ok;
 503csemi3b(_, _, _, _) -> error.
 504
 505csemi3c(A, B, X, Y) when size(A) > 1; size(B) > 2; X > Y -> ok;
 506csemi3c(_, _, _, _) -> error.
 507
 508
 509csemi4(Test) ->
 510    ok = Test({a,b}, 2, {c,d}, 2),
 511    ok = Test({1,2,3}, 0, [], 0),
 512    ok = Test({}, 2, blurf, 0),
 513    ok = Test({}, 2, {1}, 2),
 514
 515    error = Test([], 4, {}, 0),
 516    error = Test({}, 0, [a,b], 4),
 517    error = Test({}, 0, [a,b], 0),
 518    error = Test([], 0, {}, 0),
 519    error = Test({}, 0, {}, 0),
 520
 521    ok.
 522
 523csemi4a(A, X, B, Y) when (tuple_size(A) > 1) or (X > 1);
 524			 (tuple_size(B) > 1) or (Y > 1) -> ok;
 525csemi4a(_, _, _, _) -> error.
 526
 527csemi4b(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
 528			 (tuple_size(B) > 1) or (Y > 1) -> ok;
 529csemi4b(_, _, _, _) -> error.
 530
 531csemi4c(A, X, B, Y) when (tuple_size(A) > 1) or (X > 1);
 532			 (Y > 1) or (tuple_size(B) > 1) -> ok;
 533csemi4c(_, _, _, _) -> error.
 534    
 535csemi4d(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
 536			 (Y > 1) or (tuple_size(B) > 1) -> ok;
 537csemi4d(_, _, _, _) -> error.
 538
 539
 540csemi4_orelse(Test) ->
 541    ok = Test({a,b}, 2, {c,d}, 2),
 542    ok = Test({1,2,3}, 0, [], 0),
 543    ok = Test({}, 2, blurf, 0),
 544    ok = Test({}, 2, {1}, 2),
 545
 546    error = Test([], 1, {}, 0),
 547
 548    ok.
 549
 550csemi4_orelse_a(A, X, B, Y) when (tuple_size(A) > 1) orelse (X > 1);
 551			 (tuple_size(B) > 1) orelse (Y > 1) -> ok;
 552csemi4_orelse_a(_, _, _, _) -> error.
 553
 554csemi4_orelse_b(A, X, B, Y) when (X > 1) orelse (tuple_size(A) > 1);
 555			 (tuple_size(B) > 1) orelse (Y > 1) -> ok;
 556csemi4_orelse_b(_, _, _, _) -> error.
 557
 558csemi4_orelse_c(A, X, B, Y) when (tuple_size(A) > 1) orelse (X > 1);
 559                           (Y > 1) orelse (tuple_size(B) > 1) -> ok;
 560csemi4_orelse_c(_, _, _, _) -> error.
 561    
 562csemi4_orelse_d(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
 563			 (Y > 1) or (tuple_size(B) > 1) -> ok;
 564csemi4_orelse_d(_, _, _, _) -> error.
 565
 566csemi5(A, B) when hd([A+B]) > 1; abs(B) > 2 -> ok;
 567csemi5(_, _) -> error.
 568
 569csemi6(A, B) when hd([tuple_size(A)]) > 1; abs(B) > 2 -> ok;
 570csemi6(_, _) -> error.
 571    
 572csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok;
 573csemi7(_, _, _) -> error.
 574
 575csemi8(Together) ->
 576  case fun csemi8/1 of
 577      Typically when Together; Typically, Together -> ok;
 578      _ -> error
 579  end.
 580
 581
 582comma(Config) when is_list(Config) ->
 583
 584    %% ',' combinations of literal true/false.
 585
 586    check(fun() -> if true, false -> ok; true -> error end end, error),
 587    check(fun() -> if false, true -> ok; true -> error end end, error),
 588    check(fun() -> if true, true -> ok end end, ok),
 589    check(fun() -> if false, false -> ok; true -> error end end, error),
 590    check(fun() ->
 591		  {'EXIT',{if_clause,_}} =
 592		      (catch if true, false -> ok;
 593				false, true -> ok;
 594				false, false -> ok
 595			     end),
 596		  exit
 597	  end, exit),
 598
 599    %% ',' combinations of true/false in variables.
 600
 601    True = id(true),
 602    False = id(false),
 603
 604    check(fun() -> if True, False -> ok; true -> error end end, error),
 605    check(fun() -> if False, True -> ok; true -> error end end, error),
 606    check(fun() -> if True, True -> ok end end, ok),
 607    check(fun() -> if False, False -> ok; true -> error end end, error),
 608    check(fun() ->
 609		  {'EXIT',{if_clause,_}} =
 610		      (catch if True, False -> ok;
 611				False, True -> ok;
 612				False, False -> ok
 613			     end),
 614		  exit
 615	  end, exit),
 616
 617    %% ',' combinations of true/false, and non-boolean in variables.
 618
 619    Glurf = id(glurf),
 620
 621    check(fun() -> if True, Glurf -> ok; true -> error end end, error),
 622    check(fun() -> if Glurf, True -> ok; true -> error end end, error),
 623    check(fun() -> if True, True -> ok end end, ok),
 624    check(fun() -> if Glurf, Glurf -> ok; true -> error end end, error),
 625    check(fun() ->
 626		  {'EXIT',{if_clause,_}} =
 627		      (catch if True, Glurf -> ok;
 628				Glurf, True -> ok;
 629				Glurf, Glurf -> ok
 630			     end),
 631		  exit
 632	  end, exit),
 633
 634    %% ',' combinations of true/false with errors.
 635    ATuple = id({a,b,c}),
 636
 637    check(fun() -> if True, element(42, ATuple) -> ok;
 638		      true -> error end end, error),
 639    check(fun() -> if element(42, ATuple), True -> ok;
 640		      true -> error end end, error),
 641    check(fun() -> if True, True -> ok end end, ok),
 642    check(fun() -> if element(42, ATuple), element(42, ATuple) -> ok;
 643		      true -> error end end, error),
 644    check(fun() ->
 645		  {'EXIT',{if_clause,_}} =
 646		      (catch if True, element(42, ATuple) -> ok;
 647				element(42, ATuple), True -> ok;
 648				element(42, ATuple), element(42, ATuple) -> ok
 649			     end),
 650		  exit
 651	  end, exit),
 652    
 653    ok.
 654
 655or_guard(Config) when is_list(Config) ->
 656    True = id(true),
 657    False = id(false),
 658    Glurf = id(glurf),
 659
 660    %% 'or' combinations of literal true/false.
 661    check(fun() -> if true or false -> ok end end, ok),
 662    check(fun() -> if false or true -> ok end end, ok),
 663    check(fun() -> if true or true -> ok end end, ok),
 664    check(fun() -> if false or false -> ok; true -> error end end, error),
 665
 666    check(fun() -> if glurf or true -> ok; true -> error end end, error),
 667    check(fun() -> if true or glurf -> ok; true -> error end end, error),
 668    check(fun() -> if glurf or glurf -> ok; true -> error end end, error),
 669
 670    check(fun() ->
 671		  {'EXIT',{if_clause,_}} = (catch if false or false -> ok end),
 672		  exit
 673	  end, exit),
 674
 675
 676    %% 'or' combinations using variables containing true/false.
 677    check(fun() -> if True or False -> ok end end, ok),
 678    check(fun() -> if False or True -> ok end end, ok),
 679    check(fun() -> if True or True -> ok end end, ok),
 680    check(fun() -> if False or False -> ok; true -> error end end, error),
 681
 682    check(fun() -> if True or Glurf -> ok; true -> error end end, error),
 683    check(fun() -> if Glurf or True -> ok; true -> error end end, error),
 684    check(fun() -> if Glurf or Glurf -> ok; true -> error end end, error),
 685
 686    check(fun() ->
 687		  {'EXIT',{if_clause,_}} = (catch if False or False -> ok end),
 688		  exit
 689	  end, exit),
 690
 691    ok.
 692
 693more_or_guards(Config) when is_list(Config) ->
 694    True = id(true),
 695    False = id(false),
 696    ATuple = id({false,true,gurka}),
 697
 698    check(fun() ->
 699		  if element(42, ATuple) or False -> ok;
 700		     true -> error end
 701	  end, error),
 702
 703    check(fun() ->
 704		  if False or element(42, ATuple) -> ok;
 705		     true -> error end
 706	  end, error),
 707
 708    check(fun() ->
 709		  if element(18, ATuple) or element(42, ATuple) -> ok;
 710		     true -> error end
 711	  end, error),
 712
 713    check(fun() ->
 714		  if True or element(42, ATuple) -> ok;
 715		     true -> error end
 716	  end, error),
 717
 718    check(fun() ->
 719		  if element(42, ATuple) or True -> ok;
 720		     true -> error end
 721	  end, error),
 722
 723    check(fun() ->
 724		  if element(1, ATuple) or element(42, ATuple) or True -> ok;
 725		     true -> error end
 726	  end, error),
 727
 728    check(fun() ->
 729		  if element(1, ATuple) or True or element(42, ATuple) -> ok;
 730		     true -> error end
 731	  end, error),
 732
 733    check(fun() ->
 734		  if
 735		      (<<False:8>> == <<0>>) or element(2, ATuple) -> ok;
 736		      true -> error end
 737	  end, error),
 738
 739    check(fun() ->
 740		  if
 741		      element(2, ATuple) or (<<True:8>> == <<1>>) -> ok;
 742		      true -> error end
 743	  end, error),
 744
 745    check(fun() ->
 746		  if element(2, ATuple) or element(42, ATuple) -> ok;
 747		     true -> error end
 748	  end, error),
 749
 750    check(fun() ->
 751		  if
 752		      element(1, ATuple) or
 753		      element(2, ATuple) or
 754		      element(19, ATuple) -> ok;
 755		      true -> error end
 756	  end, error),
 757    ok.
 758
 759complex_or_guards(Config) when is_list(Config) ->
 760    %% complex_or_1/2
 761    ok = complex_or_1({a,b,c,d}, {1,2,3}),
 762    ok = complex_or_1({a,b,c,d}, {1}),
 763    ok = complex_or_1({a}, {1,2,3}),
 764    error = complex_or_1({a}, {1}),
 765
 766    error = complex_or_1(1, 2),
 767    error = complex_or_1([], {a,b,c,d}),
 768    error = complex_or_1({a,b,c,d}, []),
 769
 770
 771    %% complex_or_2/1
 772    ok = complex_or_2({true,{}}),
 773    ok = complex_or_2({false,{a}}),
 774    ok = complex_or_2({false,{a,b,c}}),
 775    ok = complex_or_2({true,{a,b,c,d}}),
 776
 777    error = complex_or_2({blurf,{a,b,c}}),
 778    
 779    error = complex_or_2({true}),
 780    error = complex_or_2({true,no_tuple}),
 781    error = complex_or_2({true,[]}),
 782
 783    %% complex_or_3/2
 784    ok = complex_or_3({true}, {}),
 785    ok = complex_or_3({false}, {a}),
 786    ok = complex_or_3({false}, {a,b,c}),
 787    ok = complex_or_3({true}, {a,b,c,d}),
 788    ok = complex_or_3({false}, <<1,2,3>>),
 789    ok = complex_or_3({true}, <<1,2,3,4>>),
 790
 791    error = complex_or_3(blurf, {a,b,c}),
 792
 793    error = complex_or_3({false}, <<1,2,3,4>>),
 794    error = complex_or_3([], <<1,2>>),
 795    error = complex_or_3({true}, 45),
 796    error = complex_or_3(<<>>, <<>>),
 797
 798    %% complex_or_4/2
 799    ok = complex_or_4(<<1,2,3>>, {true}),
 800    ok = complex_or_4(<<1,2,3>>, {false}),
 801    ok = complex_or_4(<<1,2,3>>, {true}),
 802    ok = complex_or_4({1,2,3}, {true}),
 803    error = complex_or_4({1,2,3,4}, {false}),
 804
 805    error = complex_or_4(<<1,2,3,4>>, []),
 806    error = complex_or_4([], {true}),
 807
 808    %% complex_or_5/2
 809    ok = complex_or_5(<<1>>, {false}),
 810    ok = complex_or_5(<<1,2,3>>, {true}),
 811    ok = complex_or_5(<<1,2,3,4>>, {false}),
 812    ok = complex_or_5({1,2,3}, {false}),
 813    ok = complex_or_5({1,2,3,4}, {false}),
 814
 815    error = complex_or_5(blurf, {false}),
 816    error = complex_or_5(<<1>>, klarf),
 817    error = complex_or_5(blurf, klarf),
 818
 819    %% complex_or_6/2
 820    ok = complex_or_6({true,true}, {1,2,3,4}),
 821    ok = complex_or_6({true,true}, <<1,2,3,4>>),
 822    ok = complex_or_6({false,false}, <<1,2,3,4>>),
 823    ok = complex_or_6({false,true}, <<1>>),
 824    ok = complex_or_6({true,false}, {1}),
 825    ok = complex_or_6({true,true}, {1}),
 826
 827    error = complex_or_6({false,false}, {1}),
 828
 829    error = complex_or_6({true}, {1,2,3,4}),
 830    error = complex_or_6({}, {1,2,3,4}),
 831    error = complex_or_6([], {1,2,3,4}),
 832    error = complex_or_6([], {1,2,3,4}),
 833    error = complex_or_6({true,false}, klurf),
 834
 835    ok.
 836
 837complex_or_1(A, B) ->
 838    if
 839	((3 < tuple_size(A)) and (tuple_size(A) < 9)) or
 840	((2 < tuple_size(B)) and (tuple_size(B) < 7)) -> ok;
 841	true -> error
 842    end.
 843
 844complex_or_2(Tuple) ->
 845    if
 846	element(1, Tuple) or not (tuple_size(element(2, Tuple)) > 3) -> ok;
 847	true -> error
 848    end.
 849
 850complex_or_3(A, B) ->
 851    if
 852	not (size(B) > 3) or element(1, A) -> ok;
 853	true -> error
 854    end.
 855
 856complex_or_4(A, B) ->
 857    if
 858	not (is_tuple(A) and (size(A) > 3)) or element(1, B) -> ok;
 859	true -> error
 860    end.
 861
 862complex_or_5(A, B) ->
 863    if
 864	not (is_tuple(A) or (size(A) > 3)) or not element(1, B) -> ok;
 865	true -> error
 866    end.
 867
 868complex_or_6(A, B) ->
 869    if
 870	not (not element(1, A) and not element(2, A)) or
 871	not (not (size(B) > 3)) -> ok;
 872	true -> error
 873    end.
 874
 875and_guard(Config) when is_list(Config) ->
 876
 877    %% 'and' combinations of literal true/false.
 878
 879    check(fun() -> if true and false -> ok; true -> error end end, error),
 880    check(fun() -> if false and true -> ok; true -> error end end, error),
 881    check(fun() -> if true and true -> ok end end, ok),
 882    check(fun() -> if false and false -> ok; true -> error end end, error),
 883
 884    check(fun() -> if glurf and true -> ok; true -> error end end, error),
 885    check(fun() -> if true and glurf -> ok; true -> error end end, error),
 886    check(fun() -> if glurf and glurf -> ok; true -> error end end, error),
 887
 888    check(fun() ->
 889		  {'EXIT',{if_clause,_}} =
 890		      (catch if true and false -> ok;
 891				false and true -> ok;
 892				false and false -> ok
 893			     end),
 894		  exit
 895	  end, exit),
 896
 897    %% 'and' combinations of true/false in variables.
 898
 899    True = id(true),
 900    False = id(false),
 901
 902    check(fun() -> if True and False -> ok; true -> error end end, error),
 903    check(fun() -> if False and True -> ok; true -> error end end, error),
 904    check(fun() -> if True and True -> ok end end, ok),
 905    check(fun() -> if False and False -> ok; true -> error end end, error),
 906    check(fun() ->
 907		  {'EXIT',{if_clause,_}} =
 908		      (catch if True and False -> ok;
 909				False and True -> ok;
 910				False and False -> ok
 911			     end),
 912		  exit
 913	  end, exit),
 914
 915    %% 'and' combinations of true/false and a non-boolean in variables.
 916
 917    Glurf = id(glurf),
 918
 919    check(fun() -> if True and Glurf -> ok; true -> error end end, error),
 920    check(fun() -> if Glurf and True -> ok; true -> error end end, error),
 921    check(fun() -> if True and True -> ok end end, ok),
 922    check(fun() -> if Glurf and Glurf -> ok; true -> error end end, error),
 923    check(fun() ->
 924		  {'EXIT',{if_clause,_}} =
 925		      (catch if True and Glurf -> ok;
 926				Glurf and True -> ok;
 927				Glurf and Glurf -> ok
 928			     end),
 929		  exit
 930	  end, exit),
 931
 932    %% 'and' combinations of true/false with errors.
 933    ATuple = id({a,b,c}),
 934
 935    check(fun() -> if True and element(42, ATuple) -> ok;
 936		      true -> error end end, error),
 937    check(fun() -> if element(42, ATuple) and True -> ok;
 938		      true -> error end end, error),
 939    check(fun() -> if True and True -> ok end end, ok),
 940    check(fun() -> if element(42, ATuple) and element(42, ATuple) -> ok;
 941		      true -> error end end, error),
 942    check(fun() ->
 943		  {'EXIT',{if_clause,_}} =
 944		      (catch if True and element(42, ATuple) -> ok;
 945				element(42, ATuple) and True -> ok;
 946				element(42, ATuple) and element(42, ATuple) -> ok
 947			     end),
 948			exit
 949		end, exit),
 950
 951    ok = relprod({'Set',a,b}, {'Set',a,b}),
 952    
 953    ok = and_same_var(42),
 954    {'EXIT',{if_clause,_}} = (catch and_same_var(x)),
 955    ok.
 956
 957and_same_var(V) ->
 958    B = is_integer(V),
 959    if
 960	B or B -> ok
 961    end.
 962
 963relprod(R1, R2) when (erlang:size(R1) =:= 3) and (erlang:element(1,R1) =:= 'Set'), (erlang:size(R2) =:= 3) and (erlang:element(1,R2) =:= 'Set') ->
 964    ok.
 965
 966
 967xor_guard(Config) when is_list(Config) ->
 968
 969    %% 'xor' combinations of literal true/false.
 970    check(fun() -> if true xor false -> ok end end, ok),
 971    check(fun() -> if false xor true -> ok end end, ok),
 972    check(fun() -> if true xor true -> ok; true -> error end end, error),
 973    check(fun() -> if false xor false -> ok; true -> error end end, error),
 974    check(fun() ->
 975		  {'EXIT',{if_clause,_}} = (catch if false xor false -> ok end),
 976		  exit
 977	  end, exit),
 978    check(fun() ->
 979		  {'EXIT',{if_clause,_}} = (catch if true xor true -> ok end),
 980		  exit
 981	  end, exit),
 982
 983
 984    %% 'xor' combinations using variables containing true/false.
 985
 986    True = id(true),
 987    False = id(false),
 988
 989    check(fun() -> if True xor False -> ok end end, ok),
 990    check(fun() -> if False xor True -> ok end end, ok),
 991    check(fun() -> if True xor True -> ok; true -> error end end, error),
 992    check(fun() -> if False xor False -> ok; true -> error end end, error),
 993    check(fun() ->
 994		  {'EXIT',{if_clause,_}} = (catch if False xor False -> ok end),
 995		  exit
 996	  end, exit),
 997    check(fun() ->
 998		  {'EXIT',{if_clause,_}} = (catch if True xor True -> ok end),
 999		  exit
1000	  end, exit),
1001
1002    ok.
1003
1004more_xor_guards(Config) when is_list(Config) ->
1005    True = id(true),
1006    False = id(false),
1007    ATuple = id({false,true,gurka}),
1008
1009    check(fun() ->
1010		  if element(42, ATuple) xor False -> ok;
1011		     true -> error end
1012	  end, error),
1013
1014    check(fun() ->
1015		  if False xor element(42, ATuple) xor False -> ok;
1016		     true -> error end
1017	  end, error),
1018
1019    check(fun() ->
1020		  if element(18, ATuple) xor element(42, ATuple) -> ok;
1021		     true -> error end
1022	  end, error),
1023
1024    check(fun() ->
1025		  if True xor element(42, ATuple) -> ok;
1026		     true -> error end
1027	  end, error),
1028
1029    check(fun() ->
1030		  if element(42, ATuple) xor True -> ok;
1031		     true -> error end
1032	  end, error),
1033    ok.
1034
1035build_in_guard(Config) when is_list(Config) ->
1036    SubBin = <<5.0/float>>,
1037    B = <<1,SubBin/binary,3.5/float>>,
1038    if
1039	B =:= <<1,SubBin/binary,3.5/float>> -> ok
1040    end.
1041
1042old_guard_tests(Config) when list(Config) ->
1043    %% Check that all the old guard tests are still recognized.
1044    list = og(Config),
1045    atom = og(an_atom),
1046    binary = og(<<1,2>>),
1047    float = og(3.14),
1048    integer = og(43),
1049    a_function = og(fun() -> ok end),
1050    pid = og(self()),
1051    reference = og(make_ref()),
1052    tuple = og({}),
1053
1054    number = on(45.333),
1055    number = on(-19),
1056    ok.
1057
1058og(V) when atom(V) -> atom;
1059og(V) when binary(V) -> binary;
1060og(V) when float(V) -> float;
1061og(V) when integer(V) -> integer;
1062og(V) when function(V) -> a_function;
1063og(V) when list(V) -> list;
1064og(V) when pid(V) -> pid;
1065og(V) when port(V) -> port;
1066og(V) when reference(V) -> reference;
1067og(V) when tuple(V) -> tuple;
1068og(_) -> what.
1069
1070on(V) when number(V) -> number;
1071on(_) -> not_number.
1072
1073complex_guard(_Config) ->
1074    _ = [true = do_complex_guard(X, Y, Z) ||
1075	    X <- [4,5], Y <- [4,5], Z <- [4,5]],
1076    _ = [true = do_complex_guard(X, Y, Z) ||
1077	    X <- [1,2,3], Y <- [1,2,3], Z <- [1,2,3]],
1078    _ = [catch do_complex_guard(X, Y, Z) ||
1079	    X <- [1,2,3,4,5], Y <- [0,6], Z <- [1,2,3,4,5]],
1080    ok.
1081
1082do_complex_guard(X1, Y1, Z1) ->
1083    if
1084	((X1 =:= 4) or (X1 =:= 5)) and
1085	((Y1 =:= 4) or (Y1 =:= 5)) and
1086	((Z1 =:= 4) or (Z1 =:= 5)) or
1087	((X1 =:= 1) or (X1 =:= 2) or (X1 =:= 3)) and
1088	((Y1 =:= 1) or (Y1 =:= 2) or (Y1 =:= 3)) and
1089	((Z1 =:= 1) or (Z1 =:= 2) or (Z1 =:= 3)) ->
1090	    true
1091    end.
1092
1093gbif(Config) when is_list(Config) ->
1094    error = gbif_1(1, {false,true}),
1095    ok = gbif_1(2, {false,true}),
1096    ok.
1097
1098gbif_1(P, T) when element(P, T) -> ok;
1099gbif_1(_, _) -> error.
1100
1101
1102t_is_boolean(Config) when is_list(Config) ->
1103    true = is_boolean(true),
1104    true = is_boolean(false),
1105    true = is_boolean(id(true)),
1106    true = is_boolean(id(false)),
1107
1108    false = is_boolean(glurf),
1109    false = is_boolean(id(glurf)),
1110
1111    false = is_boolean([]),
1112    false = is_boolean(id([])),
1113    false = is_boolean(42),
1114    false = is_boolean(id(-42)),
1115
1116    false = is_boolean(math:pi()),
1117    false = is_boolean(384793478934378924978439789873478934897),
1118
1119    false = is_boolean(id(self())),
1120    false = is_boolean(id({x,y,z})),
1121    false = is_boolean(id([a,b,c])),
1122    false = is_boolean(id(make_ref())),
1123    false = is_boolean(id(<<1,2,3>>)),
1124    false = is_boolean({id(x),y,z}),
1125    false = is_boolean([id(a),b,c]),
1126
1127    ok = bool(true),
1128    ok = bool(false),
1129    ok = bool(id(true)),
1130    ok = bool(id(false)),
1131
1132    error = bool(glurf),
1133    error = bool(id(glurf)),
1134
1135    error = bool([]),
1136    error = bool(id([])),
1137    error = bool(42),
1138    error = bool(id(-42)),
1139
1140    error = bool(math:pi()),
1141    error = bool(384793478934378924978439789873478934897),
1142
1143    error = bool(id(self())),
1144    error = bool(id({x,y,z})),
1145    error = bool(id([a,b,c])),
1146    error = bool(id(make_ref())),
1147    error = bool(id(<<1,2,3>>)),
1148
1149    true = my_is_bool(true),
1150    true = my_is_bool(false),
1151    false = my_is_bool([]),
1152    false = my_is_bool([1,2,3,4]),
1153    false = my_is_bool({a,b,c}),
1154
1155    ok.
1156
1157bool(X) when is_boolean(X) -> ok;
1158bool(_) -> error.
1159
1160my_is_bool(V) ->
1161    Res = my_is_bool_a(V),
1162    Res = my_is_bool_b(V).
1163
1164my_is_bool_a(V) ->
1165    case V of
1166	true -> true;
1167	false -> true;
1168	_ -> false
1169    end.
1170
1171my_is_bool_b(V) ->
1172    case V of
1173	false -> true;
1174	true -> true;
1175	_ -> false
1176    end.
1177
1178is_function_2(Config) when is_list(Config) ->
1179    true = is_function(id(fun ?MODULE:all/1), 1),
1180    true = is_function(id(fun() -> ok end), 0),
1181    false = is_function(id(fun ?MODULE:all/1), 0),
1182    false = is_function(id(fun() -> ok end), 1),
1183    {'EXIT',{badarg,_}} =
1184        (catch is_function(id(fun() -> ok end), -1) orelse error),
1185    {'EXIT',{badarg,_}} =
1186        (catch is_function(id(fun() -> ok end), '') orelse error),
1187
1188    F = fun(_) -> ok end,
1189    if
1190	is_function(F, 1) -> ok
1191    end.
1192
1193tricky(Config) when is_list(Config) ->
1194    not_ok = tricky_1(1, 2),
1195    not_ok = tricky_1(1, blurf),
1196    not_ok = tricky_1(foo, 2),
1197    not_ok = tricky_1(a, b),
1198
1199    error = tricky_2(0.5),
1200    error = tricky_2(a),
1201    error = tricky_2({a,b,c}),
1202
1203    false = rb(100000, [1], 42),
1204    true = rb(100000, [], 42),
1205    true = rb(555, [a,b,c], 19),
1206
1207    error = tricky_3(42),
1208    error = tricky_3(42.0),
1209    error = tricky_3(<<>>),
1210    error = tricky_3(#{}),
1211    error = tricky_3({a,b}),
1212
1213    ok.
1214
1215tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok;
1216tricky_1(_, _) -> not_ok.
1217
1218tricky_2(X) when float(X) or float(X) -> ok;
1219tricky_2(_) -> error.
1220
1221tricky_3(X)
1222  when abs(X) or bit_size(X) or byte_size(X) or ceil(X) or
1223       float(X) or floor(X) or length(X) or
1224       map_size(X) or node() or node(X) or round(X) or
1225       self() or size(X) or tl(X) or trunc(X) or tuple_size(X) ->
1226    ok;
1227tricky_3(_) ->
1228    error.
1229
1230%% From dets_v9:read_buckets/11, simplified.
1231
1232rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true;
1233rb(_, _, _) -> false.
1234
1235
1236-define(T(Op,A,B),
1237	ok = if A Op B -> ok; true -> error end,
1238	ok = if not (A Op B) -> error; true -> ok end,
1239	(fun(X, Y, True, False) -> 
1240		 ok = if X Op Y -> ok; true -> error end,
1241		 ok = if False; X Op Y; False -> ok; true -> error end,
1242		 ok = if X Op Y, True -> ok; true -> error end,
1243		 ok = if not (X Op Y) -> error; true -> ok end,
1244		 ok = if False; not (X Op Y); False -> error; true -> ok end
1245	 end)(id(A), id(B), id(true), id(false))).
1246
1247-define(F(Op,A,B),
1248	ok = if A Op B -> error; true -> ok end,
1249	ok = if not (A Op B) -> ok; true -> error end,
1250	(fun(X, Y, True, False) ->
1251		 ok = if X Op Y -> error; true -> ok end,
1252		 ok = if False; X Op Y; False -> error; true -> ok end,
1253		 ok = if not (X Op Y); False -> ok; true -> error end,
1254		 ok = if not (X Op Y), True -> ok; true -> error end
1255	 end)(id(A), id(B), id(true), id(false))).
1256
1257
1258rel_ops(Config) when is_list(Config) ->
1259    ?T(=/=, 1, 1.0),
1260    ?F(=/=, 2, 2),
1261    ?F(=/=, {a}, {a}),
1262
1263    ?F(/=, a, a),
1264    ?F(/=, 0, 0.0),
1265    ?T(/=, 0, 1),
1266    ?F(/=, {a}, {a}),
1267
1268    ?T(==, 1, 1.0),
1269    ?F(==, a, {}),
1270
1271    ?F(=:=, 1, 1.0),
1272    ?T(=:=, 42.0, 42.0),
1273
1274    ?F(>, a, b),
1275    ?T(>, 42, 1.0),
1276    ?F(>, 42, 42.0),
1277
1278    ?T(<, a, b),
1279    ?F(<, 42, 1.0),
1280    ?F(<, 42, 42.0),
1281
1282    ?T(=<, 1.5, 5),
1283    ?F(=<, -9, -100.344),
1284    ?T(=<, 42, 42.0),
1285
1286    ?T(>=, 42, 42.0),
1287    ?F(>=, a, b),
1288    ?T(>=, 1.0, 0),
1289
1290    %% Coverage of beam_block:is_exact_eq_ok/1 and collect/1.
1291    true = any_atom /= id(42),
1292    true = [] /= id(42),
1293
1294    %% Coverage of beam_utils:bif_to_test/3
1295    Empty = id([]),
1296    ?T(==, [], Empty),
1297
1298    %% Cover beam_ssa_dead:turn_op('/=').
1299    ok = (fun(A, B) when is_atom(A) ->
1300                  X = id(A /= B),
1301                  if
1302                      X -> ok;
1303                      true -> error
1304                  end
1305          end)(a, b),
1306    ok = (fun(A, B) when is_atom(A) ->
1307                  X = id(B /= A),
1308                  if
1309                        X -> ok;
1310                        true -> error
1311                    end
1312            end)(a, b),
1313
1314    %% Cover beam_ssa_dead.
1315    Arrow = fun([T1,T2]) when T1 == $>, T2 == $>;
1316                              T1 == $<, T2 == $| ->  true;
1317               (_) -> false
1318            end,
1319    true = Arrow(">>"),
1320    true = Arrow("<|"),
1321    false = Arrow("><"),
1322    false = Arrow(""),
1323
1324    ok.
1325
1326-undef(TestOp).
1327
1328rel_op_combinations(Config) when is_list(Config) ->
1329    Digits0 = lists:seq(16#0030, 16#0039) ++
1330	lists:seq(16#0660, 16#0669) ++
1331	lists:seq(16#06F0, 16#06F9),
1332    Digits = gb_sets:from_list(Digits0),
1333    rel_op_combinations_1(16#0700, Digits),
1334
1335    BrokenRange0 = lists:seq(3, 5) ++
1336	lists:seq(10, 12) ++ lists:seq(14, 20),
1337    BrokenRange = gb_sets:from_list(BrokenRange0),
1338    rel_op_combinations_2(30, BrokenRange),
1339
1340    Red0 = [{I,2*I} || I <- lists:seq(0, 50)] ++
1341	[{I,5*I} || I <- lists:seq(51, 80)],
1342    Red = gb_trees:from_orddict(Red0),
1343    rel_op_combinations_3(100, Red).
1344
1345rel_op_combinations_1(0, _) ->
1346    ok;
1347rel_op_combinations_1(N, Digits) ->
1348    Bool = gb_sets:is_member(N, Digits),
1349    Bool = is_digit_1(N),
1350    Bool = is_digit_2(N),
1351    Bool = is_digit_3(N),
1352    Bool = is_digit_4(N),
1353    Bool = is_digit_5(N),
1354    Bool = is_digit_6(N),
1355    Bool = is_digit_7(N),
1356    Bool = is_digit_8(N),
1357    Bool = is_digit_9(42, N),
1358    Bool = is_digit_10(N, 0),
1359    Bool = is_digit_11(N, 0),
1360    rel_op_combinations_1(N-1, Digits).
1361
1362is_digit_1(X) when 16#0660 =< X, X =< 16#0669 -> true;
1363is_digit_1(X) when 16#0030 =< X, X =< 16#0039 -> true;
1364is_digit_1(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1365is_digit_1(_) -> false.
1366
1367is_digit_2(X) when (16#0030-1) < X, X =< 16#0039 -> true;
1368is_digit_2(X) when (16#0660-1) < X, X =< 16#0669 -> true;
1369is_digit_2(X) when (16#06F0-1) < X, X =< 16#06F9 -> true;
1370is_digit_2(_) -> false.
1371
1372is_digit_3(X) when 16#0660 =< X, X < (16#0669+1) -> true;
1373is_digit_3(X) when 16#0030 =< X, X < (16#0039+1) -> true;
1374is_digit_3(X) when 16#06F0 =< X, X < (16#06F9+1) -> true;
1375is_digit_3(_) -> false.
1376
1377is_digit_4(X) when (16#0660-1) < X, X < (16#0669+1) -> true;
1378is_digit_4(X) when (16#0030-1) < X, X < (16#0039+1) -> true;
1379is_digit_4(X) when (16#06F0-1) < X, X < (16#06F9+1) -> true;
1380is_digit_4(_) -> false.
1381
1382is_digit_5(X) when X >= 16#0660, X =< 16#0669 -> true;
1383is_digit_5(X) when X >= 16#0030, X =< 16#0039 -> true;
1384is_digit_5(X) when X >= 16#06F0, X =< 16#06F9 -> true;
1385is_digit_5(_) -> false.
1386
1387is_digit_6(X) when X > (16#0660-1), X =< 16#0669 -> true;
1388is_digit_6(X) when X > (16#0030-1), X =< 16#0039 -> true;
1389is_digit_6(X) when X > (16#06F0-1), X =< 16#06F9 -> true;
1390is_digit_6(_) -> false.
1391
1392is_digit_7(X) when 16#0660 =< X, X =< 16#0669 -> true;
1393is_digit_7(X) when 16#0030 =< X, X =< 16#003A, X =/= 16#003A -> true;
1394is_digit_7(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1395is_digit_7(_) -> false.
1396
1397is_digit_8(X) when X =< 16#0039, X > (16#0030-1) -> true;
1398is_digit_8(X) when X =< 16#06F9, X > (16#06F0-1) -> true;
1399is_digit_8(X) when X =< 16#0669, X > (16#0660-1) -> true;
1400is_digit_8(16#0670) -> false;
1401is_digit_8(_) -> false.
1402
1403is_digit_9(A, 0) when A =:= 42 -> false;
1404is_digit_9(_, X) when X > 16#065F, X < 16#066A -> true;
1405is_digit_9(_, X) when 16#0030 =< X, X =< 16#0039 -> true;
1406is_digit_9(_, X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1407is_digit_9(_, _) -> false.
1408
1409is_digit_10(0, 0) -> false;
1410is_digit_10(X, _) when X < 16#066A, 16#0660 =< X -> true;
1411is_digit_10(X, _) when 16#0030 =< X, X =< 16#0039 -> true;
1412is_digit_10(X, _) when 16#06F0 =< X, X =< 16#06F9 -> true;
1413is_digit_10(_, _) -> false.
1414
1415is_digit_11(0, 0) -> false;
1416is_digit_11(X, _) when X =< 16#0669, 16#0660 =< X -> true;
1417is_digit_11(X, _) when 16#0030 =< X, X =< 16#0039 -> true;
1418is_digit_11(X, _) when 16#06F0 =< X, X =< 16#06F9 -> true;
1419is_digit_11(_, _) -> false.
1420
1421rel_op_combinations_2(0, _) ->
1422    ok;
1423rel_op_combinations_2(N, Range) ->
1424    Bool = gb_sets:is_member(N, Range),
1425    Bool = broken_range_1(N),
1426    Bool = broken_range_2(N),
1427    Bool = broken_range_3(N),
1428    Bool = broken_range_4(N),
1429    Bool = broken_range_5(N),
1430    Bool = broken_range_6(N),
1431    Bool = broken_range_7(N),
1432    Bool = broken_range_8(N),
1433    Bool = broken_range_9(N),
1434    Bool = broken_range_10(N),
1435    Bool = broken_range_11(N),
1436    Bool = broken_range_12(N),
1437    Bool = broken_range_13(N),
1438    rel_op_combinations_2(N-1, Range).
1439
1440broken_range_1(X) when X >= 10, X =< 20, X =/= 13 -> true;
1441broken_range_1(X) when X >= 3, X =< 5 -> true;
1442broken_range_1(_) -> false.
1443
1444broken_range_2(X) when X >= 10, X =< 12 -> true;
1445broken_range_2(X) when X >= 14, X =< 20 -> true;
1446broken_range_2(X) when X >= 3, X =< 5 -> true;
1447broken_range_2(_) -> false.
1448
1449broken_range_3(X) when X >= 10, X =< 12 -> true;
1450broken_range_3(X) when X >= 14, X < 21 -> true;
1451broken_range_3(3) -> true;
1452broken_range_3(4) -> true;
1453broken_range_3(5) -> true;
1454broken_range_3(_) -> false.
1455
1456broken_range_4(X) when X =< 5, X >= 3 -> true;
1457broken_range_4(X) when X >= 10, X =< 20, X =/= 13 -> true;
1458broken_range_4(X) when X =< 100 -> false;
1459broken_range_4(_) -> false.
1460
1461broken_range_5(X) when X >= 10, X =< 20, X =/= 13 -> true;
1462broken_range_5(X) when X > 2, X =< 5 -> true;
1463broken_range_5(_) -> false.
1464
1465broken_range_6(X) when X >= 10, X =< 20, X =/= 13 -> true;
1466broken_range_6(X) when X > 2, X < 6 -> true;
1467broken_range_6(_) -> false.
1468
1469broken_range_7(X) when X > 2, X < 6 -> true;
1470broken_range_7(X) when X >= 10, X =< 20, X =/= 13 -> true;
1471broken_range_7(X) when X > 30 -> false;
1472broken_range_7(_) -> false.
1473
1474broken_range_8(X) when X >= 10, X =< 20, X =/= 13 -> true;
1475broken_range_8(X) when X =:= 3 -> true;
1476broken_range_8(X) when X >= 3, X =< 5 -> true;
1477broken_range_8(_) -> false.
1478
1479broken_range_9(X) when X >= 10, X =< 20, X =/= 13 -> true;
1480broken_range_9(X) when X =:= 13 -> false;
1481broken_range_9(X) when X >= 3, X =< 5 -> true;
1482broken_range_9(_) -> false.
1483
1484broken_range_10(X) when X >= 3, X =< 5 -> true;
1485broken_range_10(X) when X >= 10, X =< 20, X =/= 13 -> true;
1486broken_range_10(X) when X =/= 13 -> false;
1487broken_range_10(_) -> false.
1488
1489broken_range_11(X) when X >= 10, X =< 20, X =/= 13 -> true;
1490broken_range_11(X) when is_tuple(X), X =:= 10 -> true;
1491broken_range_11(X) when X >= 3, X =< 5 -> true;
1492broken_range_11(_) -> false.
1493
1494broken_range_12(X) when X >= 3, X =< 5 -> true;
1495broken_range_12(X) when X >= 10, X =< 20, X =/= 13 -> true;
1496broken_range_12(X) when X < 30, X > 20 -> false;
1497broken_range_12(_) -> false.
1498
1499broken_range_13(X) when X >= 10, X =< 20, 13 =/= X -> true;
1500broken_range_13(X) when X >= 3, X =< 5 -> true;
1501broken_range_13(_) -> false.
1502
1503rel_op_combinations_3(0, _) ->
1504    ok;
1505rel_op_combinations_3(N, Red) ->
1506    Val = case gb_trees:lookup(N, Red) of
1507	      none -> none;
1508	      {value,V} -> V
1509	  end,
1510    Val = redundant_1(N),
1511    Val = redundant_2(N),
1512    Val = redundant_3(N),
1513    Val = redundant_4(N),
1514    Val = redundant_5(N),
1515    Val = redundant_6(N),
1516    Val = redundant_7(N),
1517    Val = redundant_8(N),
1518    Val = redundant_9(N),
1519    Val = redundant_10(N),
1520    Val = redundant_11(N),
1521    Val = redundant_11(N),
1522    rel_op_combinations_3(N-1, Red).
1523
1524redundant_1(X) when X >= 51, X =< 80 -> 5*X;
1525redundant_1(X) when X < 51 -> 2*X;
1526redundant_1(_) -> none.
1527
1528redundant_2(X) when X < 51 -> 2*X;
1529redundant_2(X) when X >= 51, X =< 80 -> 5*X;
1530redundant_2(_) -> none.
1531
1532redundant_3(X) when X < 51 -> 2*X;
1533redundant_3(X) when X =< 80, X >= 51 -> 5*X;
1534redundant_3(X) when X =/= 100 -> none;
1535redundant_3(_) -> none.
1536
1537redundant_4(X) when X < 51 -> 2*X;
1538redundant_4(X) when X =< 80, X > 50 -> 5*X;
1539redundant_4(X) when X =/= 100 -> none;
1540redundant_4(_) -> none.
1541
1542redundant_5(X) when X < 51 -> 2*X;
1543redundant_5(X) when X > 50, X < 81 -> 5*X;
1544redundant_5(X) when X =< 10 -> none;
1545redundant_5(_) -> none.
1546
1547redundant_6(X) when X > 50, X =< 80 -> 5*X;
1548redundant_6(X) when X < 51 -> 2*X;
1549redundant_6(_) -> none.
1550
1551redundant_7(X) when is_integer(X), X >= 51, X =< 80 -> 5*X;
1552redundant_7(X) when is_integer(X), X < 51 -> 2*X;
1553redundant_7(_) -> none.
1554
1555redundant_8(X) when X >= 51, X =< 80 -> 5*X;
1556redundant_8(X) when X < 51 -> 2*X;
1557redundant_8(_) -> none.
1558
1559redundant_9(X) when X >= 51, X =< 80 -> 5*X;
1560redundant_9(X) when X < 51 -> 2*X;
1561redundant_9(90) -> none;
1562redundant_9(X) when X =/= 90 -> none;
1563redundant_9(_) -> none.
1564
1565redundant_10(X) when X >= 51, X =< 80 -> 5*X;
1566redundant_10(X) when X < 51 -> 2*X;
1567redundant_10(90) -> none;
1568redundant_10(X) when X =:= 90 -> none;
1569redundant_10(_) -> none.
1570
1571redundant_11(X) when X < 51 -> 2*X;
1572redundant_11(X) when X =:= 10 -> 2*X;
1573redundant_11(X) when X >= 51, X =< 80 -> 5*X;
1574redundant_11(_) -> none.
1575
1576redundant_12(X) when X >= 50, X =< 80 -> 2*X;
1577redundant_12(X) when X < 51 -> 5*X;
1578redundant_12(_) -> none.
1579
1580%% Test type tests on literal values. (From emulator test suites.)
1581literal_type_tests(Config) when is_list(Config) ->
1582    case ?MODULE of
1583	guard_SUITE -> literal_type_tests_1(Config);
1584	_ -> {skip,"Enough to run this case once."}
1585    end.
1586
1587literal_type_tests_1(Config) ->
1588    %% Generate an Erlang module with all different type of type tests.
1589    Tests = make_test([{T,L} || T <- type_tests(), L <- literals()] ++
1590			    [{is_function,L1,L2} || 
1591				L1 <- literals(), L2 <- literals()]),
1592    Mod = literal_test,
1593    Anno = erl_anno:new(0),
1594    Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
1595    Form = [{attribute,Anno,module,Mod},
1596            {attribute,Anno,compile,export_all},
1597            Func, {eof,999}],
1598
1599    %% Print generated code for inspection.
1600    lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
1601
1602    %% Test compile:form/1.  This implies full optimization (default).
1603    {ok,Mod,Code1} = compile:forms(Form),
1604    smoke_disasm(Config, Mod, Code1),
1605    {module,Mod} = code:load_binary(Mod, Mod, Code1),
1606    Mod:test(),
1607    true = code:delete(Mod),
1608    code:purge(Mod),
1609			       
1610    %% Test compile:form/2.  Turn off all optimizations.
1611    {ok,Mod,Code2} = compile:forms(Form, [binary,report,time,
1612						no_copt,no_postopt]),
1613    smoke_disasm(Config, Mod, Code2),
1614    {module,Mod} = code:load_binary(Mod, Mod, Code2),
1615    Mod:test(),
1616    true = code:delete(Mod),
1617    code:purge(Mod),
1618    ok.
1619
1620make_test([{T,L1,L2}|Ts]) ->
1621    [test(T, L1, L2)|make_test(Ts)];
1622make_test([{T,L}|Ts]) ->
1623    [test(T, L)|make_test(Ts)];
1624make_test([]) -> [].
1625
1626test(T, L) ->
1627    S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T,L,T,L]),
1628    S = lists:flatten(S0),
1629    {ok,Toks,_Line} = erl_scan:string(S),
1630    {ok,E} = erl_parse:parse_exprs(Toks),
1631    {value,Val,_Bs} = erl_eval:exprs(E, []),
1632    Anno = erl_anno:new(0),
1633    {match,Anno,{atom,Anno,Val},hd(E)}.
1634
1635test(T, L1, L2) ->
1636    S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ", [T,L1,L2,T,L1,L2]),
1637    S = lists:flatten(S0),
1638    {ok,Toks,_Line} = erl_scan:string(S),
1639    {ok,E} = erl_parse:parse_exprs(Toks),
1640    {value,Val,_Bs} = erl_eval:exprs(E, []),
1641    Anno = erl_anno:new(0),
1642    {match,Anno,{atom,Anno,Val},hd(E)}.
1643
1644smoke_disasm(Config, Mod, Bin) ->
1645    Priv = proplists:get_value(priv_dir, Config),
1646    File = filename:join(Priv, atom_to_list(Mod)++".beam"),
1647    ok = file:write_file(File, Bin),
1648    test_lib:smoke_disasm(File).
1649
1650literals() ->
1651    [42,
1652     3.14,
1653     -3,
1654     32982724987789283473473838474,
1655     [],
1656     xxxx,
1657     {a,b,c},
1658     [a,list],
1659     <<1,2,3>>,
1660     <<42:17>>].
1661
1662type_tests() ->
1663    [is_boolean,
1664     is_integer,
1665     is_float,
1666     is_number,
1667     is_atom,
1668     is_list,
1669     is_tuple,
1670     is_pid,
1671     is_reference,
1672     is_port,
1673     is_binary,
1674     is_bitstring,
1675     is_function,
1676     is_map].
1677
1678basic_andalso_orelse(Config) when is_list(Config) ->
1679    T = id({type,integers,23,42}),
1680    65 = if
1681	     ((element(1, T) =:= type) andalso (tuple_size(T) =:= 4) andalso
1682	      element(2, T)) == integers ->
1683		 element(3, T) + element(4, T);
1684	     true -> error
1685	 end,
1686    65 = case [] of
1687	     [] when ((element(1, T) =:= type) andalso (tuple_size(T) =:= 4) andalso
1688		      element(2, T)) == integers ->
1689		 element(3, T) + element(4, T)
1690	 end,
1691
1692    42 = basic_rt({type,integers,40,2}),
1693    5.0 = basic_rt({vector,{3.0,4.0}}),
1694    20 = basic_rt(['+',3,7]),
1695    {'Set',a,b} = basic_rt({{'Set',a,b},{'Set',a,b}}),
1696    12 = basic_rt({klurf,4}),
1697
1698    error = basic_rt({type,integers,40,2,3}),
1699    error = basic_rt({kalle,integers,40,2}),
1700    error = basic_rt({kalle,integers,40,2}),
1701    error = basic_rt({1,2}),
1702    error = basic_rt([]),
1703
1704    RelProdBody =
1705	fun(R1, R2) ->
1706		if
1707		    (erlang:size(R1) =:= 3) andalso (erlang:element(1,R1) =:= 'Set'),
1708		    (erlang:size(R2) =:= 3) andalso (erlang:element(1,R2) =:= 'Set') ->
1709			ok
1710		end
1711	end,
1712
1713    ok = RelProdBody({'Set',a,b}, {'Set',a,b}),
1714
1715    %% 'andalso'/'orelse' with calls known to fail already at compile time.
1716    %% Used to crash the code generator.

Large files files are truncated, but you can click here to view the full file