PageRenderTime 195ms CodeModel.GetById 3ms app.highlight 178ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/compiler/test/guard_SUITE.erl

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

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