/lib/compiler/test/guard_SUITE.erl
Erlang | 2277 lines | 1761 code | 393 blank | 123 comment | 212 complexity | 03a13aa4038ad066497dd8c8125137f1 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, Apache-2.0
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. 1717 error = (fun() -> 1718 R = {vars,true}, 1719 if 1720 is_record(R, vars, 2) andalso element(99, R) -> ok; 1721 true -> error 1722 end 1723 end)(), 1724 error = (fun(X) -> 1725 L = {a,b,c}, 1726 if 1727 is_list(X) andalso length(L) > 4 -> ok; 1728 true -> error 1729 end 1730 end)([]), 1731 ok. 1732 1733basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 4 andalso element(1, T) =:= type andalso 1734 element(2, T) == integers -> 1735 element(3, T) + element(4, T); 1736basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 2 andalso element(1, T) =:= vector -> 1737 {X,Y} = element(2, T), 1738 if 1739 is_float(X), is_float(Y) -> 1740 math:sqrt(X*X+Y*Y) 1741 end; 1742basic_rt(['+',A,B]) -> 1743 2*id(A+B); 1744basic_rt({R1,R2}) when erlang:size(R1) =:= 3 andalso erlang:element(1,R1) =:= 'Set', 1745 erlang:size(R2) =:= 3 andalso erlang:element(1,R2) =:= 'Set' -> 1746 R1 = id(R1), 1747 R2 = id(R2), 1748 R1; 1749basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 2 andalso element(1, T) =:= klurf -> 1750 3*id(element(2, T)); 1751basic_rt(_) -> 1752 error. 1753 1754traverse_dcd(Config) when is_list(Config) -> 1755 L0 = [{log_header,dcd_log,"1.0",a,b,c},{log_header,dcd_log,"2.0",a,b,c}, 1756 {log_header,dcd_log,"0.0",a,b,c},blurf], 1757 {cont,[{log_header,dcd_log,"0.0",a,b,c},blurf],log,funny} = 1758 traverse_dcd({cont,L0}, log, funny), 1759 L1 = [{log_header,dcd_log,"1.0"}], 1760 {cont,L1,log,funny} = traverse_dcd({cont,L1}, log, funny), 1761 L2 = [{a,tuple}], 1762 {cont,L2,log,funny} = traverse_dcd({cont,L2}, log, funny), 1763 ok. 1764 1765%% The function starts out with 3 arguments in {x,0}, {x,1}, {x,2}. 1766%% The outer match of a two tuple will places the first element in {x,3} and 1767%% second in {x,4}. The guard for the first clause must make ensure that all of those 1768%% registers are restored before entering the second clause. 1769%% 1770%% (From mnesia_checkpoint.erl, modified.) 1771 1772traverse_dcd({Cont,[LogH|Rest]},Log,Fun) 1773 when is_tuple(LogH) andalso tuple_size(LogH) =:= 6 andalso element(1, LogH) =:= log_header 1774andalso erlang:element(2,LogH) == dcd_log, 1775is_tuple(LogH) andalso tuple_size(LogH) =:= 6 andalso element(1, LogH) =:= log_header 1776andalso erlang:element(3,LogH) >= "1.0" -> 1777 traverse_dcd({Cont,Rest},Log,Fun); 1778traverse_dcd({Cont,Recs},Log,Fun) -> 1779 {Cont,Recs,Log,Fun}. 1780 1781 1782check_qlc_hrl(Config) when is_list(Config) -> 1783 St = {r1,false,dum}, 1784 foo = cqlc(qlc, q, [{lc,1,2,3}], St), 1785 foo = cqlc(qlc, q, [{lc,1,2,3},b], St), 1786 St = cqlc(qlc, q, [], St), 1787 St = cqlc(qlc, blurf, [{lc,1,2,3},b], St), 1788 St = cqlc(q, q, [{lc,1,2,3},b], St), 1789 St = cqlc(qlc, q, [{lc,1,2,3},b,c], St), 1790 St = cqlc(qlc, q, [a,b], St), 1791 {r1,true,kalle} = cqlc(qlc, q, [{lc,1,2,3},b], {r1,true,kalle}), 1792 ok. 1793 1794%% From erl_lint.erl; original name was check_qlc_hrl/4. 1795cqlc(M, F, As, St) -> 1796 Arity = length(As), 1797 case As of 1798 [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q, 1799 Arity < 3, 1800 not (((element(1, St) =:= r1) orelse fail) and (tuple_size(St) =:= 3) and element(2, St)) -> 1801 foo; 1802 _ -> 1803 St 1804 end. 1805 1806%% OTP-7679: Thanks to Hunter Morris. 1807andalso_semi(Config) when is_list(Config) -> 1808 ok = andalso_semi_foo(0), 1809 ok = andalso_semi_foo(1), 1810 fc(catch andalso_semi_foo(2)), 1811 1812 ok = andalso_semi_bar([a,b,c]), 1813 ok = andalso_semi_bar(1), 1814 fc(catch andalso_semi_bar([a,b])), 1815 ok. 1816 1817andalso_semi_foo(Bar) when is_integer(Bar) andalso Bar =:= 0; Bar =:= 1 -> 1818 ok. 1819 1820andalso_semi_bar(Bar) when is_list(Bar) andalso length(Bar) =:= 3; Bar =:= 1 -> 1821 ok. 1822 1823 1824t_tuple_size(Config) when is_list(Config) -> 1825 10 = do_tuple_size({1,2,3,4}), 1826 fc(catch do_tuple_size({1,2,3})), 1827 fc(catch do_tuple_size(42)), 1828 1829 error = ludicrous_tuple_size({a,b,c}), 1830 error = ludicrous_tuple_size([a,b,c]), 1831 1832 good_ip({1,2,3,4}), 1833 good_ip({1,2,3,4,5,6,7,8}), 1834 error = validate_ip({42,11}), 1835 error = validate_ip(atom), 1836 1837 ok. 1838 1839do_tuple_size(T) when tuple_size(T) =:= 4 -> 1840 {A,B,C,D} = T, 1841 A+B+C+D. 1842 1843ludicrous_tuple_size(T) 1844 when tuple_size(T) =:= 16#7777777777777777777777777777777777 -> ok; 1845ludicrous_tuple_size(T) 1846 when tuple_size(T) =:= 16#10000000000000000 -> ok; 1847ludicrous_tuple_size(T) 1848 when tuple_size(T) =:= (1 bsl 64) - 1 -> ok; 1849ludicrous_tuple_size(T) 1850 when tuple_size(T) =:= 16#FFFFFFFFFFFFFFFF -> ok; 1851ludicrous_tuple_size(_) -> error. 1852 1853good_ip(IP) -> 1854 IP = validate_ip(IP). 1855 1856validate_ip(Value) when is_tuple(Value) andalso 1857 ((size(Value) =:= 4) orelse (size(Value) =:= 8)) -> 1858 %% size/1 (converted to tuple_size) used more than once. 1859 Value; 1860validate_ip(_) -> 1861 error. 1862 1863%% 1864%% The binary_part/2,3 guard BIFs 1865%% 1866-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))). 1867mask_error({'EXIT',{Err,_}}) -> 1868 Err; 1869mask_error(Else) -> 1870 Else. 1871 1872%% Test the binary_part/2,3 guard (GC) BIFs. 1873binary_part(Config) when is_list(Config) -> 1874 %% This is more or less a copy of what the guard_SUITE in emulator 1875 %% does to cover the guard bif's 1876 1 = bptest(<<1,2,3>>), 1877 2 = bptest(<<2,1,3>>), 1878 error = bptest(<<1>>), 1879 error = bptest(<<>>), 1880 error = bptest(apa), 1881 3 = bptest(<<2,3,3>>), 1882 % With one variable (pos) 1883 1 = bptest(<<1,2,3>>,1), 1884 2 = bptest(<<2,1,3>>,1), 1885 error = bptest(<<1>>,1), 1886 error = bptest(<<>>,1), 1887 error = bptest(apa,1), 1888 3 = bptest(<<2,3,3>>,1), 1889 % With one variable (length) 1890 1 = bptesty(<<1,2,3>>,1), 1891 2 = bptesty(<<2,1,3>>,1), 1892 error = bptesty(<<1>>,1), 1893 error = bptesty(<<>>,1), 1894 error = bptesty(apa,1), 1895 3 = bptesty(<<2,3,3>>,2), 1896 % With one variable (whole tuple) 1897 1 = bptestx(<<1,2,3>>,{1,1}), 1898 2 = bptestx(<<2,1,3>>,{1,1}), 1899 error = bptestx(<<1>>,{1,1}), 1900 error = bptestx(<<>>,{1,1}), 1901 error = bptestx(apa,{1,1}), 1902 3 = bptestx(<<2,3,3>>,{1,2}), 1903 % With two variables 1904 1 = bptest(<<1,2,3>>,1,1), 1905 2 = bptest(<<2,1,3>>,1,1), 1906 error = bptest(<<1>>,1,1), 1907 error = bptest(<<>>,1,1), 1908 error = bptest(apa,1,1), 1909 3 = bptest(<<2,3,3>>,1,2), 1910 % Direct (autoimported) call, these will be evaluated by the compiler... 1911 <<2>> = binary_part(<<1,2,3>>,1,1), 1912 <<1>> = binary_part(<<2,1,3>>,1,1), 1913 % Compiler warnings due to constant evaluation expected (3) 1914 badarg = ?MASK_ERROR(binary_part(<<1>>,1,1)), 1915 badarg = ?MASK_ERROR(binary_part(<<>>,1,1)), 1916 badarg = ?MASK_ERROR(binary_part(apa,1,1)), 1917 <<3,3>> = binary_part(<<2,3,3>>,1,2), 1918 % Direct call through apply 1919 <<2>> = apply(erlang,binary_part,[<<1,2,3>>,1,1]), 1920 <<1>> = apply(erlang,binary_part,[<<2,1,3>>,1,1]), 1921 % Compiler warnings due to constant evaluation expected (3) 1922 badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<1>>,1,1])), 1923 badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<>>,1,1])), 1924 badarg = ?MASK_ERROR(apply(erlang,binary_part,[apa,1,1])), 1925 <<3,3>> = apply(erlang,binary_part,[<<2,3,3>>,1,2]), 1926 % Constant propagation 1927 Bin = <<1,2,3>>, 1928 ok = if 1929 binary_part(Bin,1,1) =:= <<2>> -> 1930 ok; 1931 %% Compiler warning, clause cannot match (expected) 1932 true -> 1933 error 1934 end, 1935 ok = if 1936 binary_part(Bin,{1,1}) =:= <<2>> -> 1937 ok; 1938 %% Compiler warning, clause cannot match (expected) 1939 true -> 1940 error 1941 end, 1942 ok. 1943 1944 1945bptest(B) when length(B) =:= 1337 -> 1946 1; 1947bptest(B) when binary_part(B,{1,1}) =:= <<2>> -> 1948 1; 1949bptest(B) when erlang:binary_part(B,1,1) =:= <<1>> -> 1950 2; 1951bptest(B) when erlang:binary_part(B,{1,2}) =:= <<3,3>> -> 1952 3; 1953bptest(_) -> 1954 error. 1955 1956bptest(B,A) when length(B) =:= A -> 1957 1; 1958bptest(B,A) when binary_part(B,{A,1}) =:= <<2>> -> 1959 1; 1960bptest(B,A) when erlang:binary_part(B,A,1) =:= <<1>> -> 1961 2; 1962bptest(B,A) when erlang:binary_part(B,{A,2}) =:= <<3,3>> -> 1963 3; 1964bptest(_,_) -> 1965 error. 1966 1967bptestx(B,A) when length(B) =:= A -> 1968 1; 1969bptestx(B,A) when binary_part(B,A) =:= <<2>> -> 1970 1; 1971bptestx(B,A) when erlang:binary_part(B,A) =:= <<1>> -> 1972 2; 1973bptestx(B,A) when erlang:binary_part(B,A) =:= <<3,3>> -> 1974 3; 1975bptestx(_,_) -> 1976 error. 1977 1978bptesty(B,A) when length(B) =:= A -> 1979 1; 1980bptesty(B,A) when binary_part(B,{1,A}) =:= <<2>> -> 1981 1; 1982bptesty(B,A) when erlang:binary_part(B,1,A) =:= <<1>> -> 1983 2; 1984bptesty(B,A) when erlang:binary_part(B,{1,A}) =:= <<3,3>> -> 1985 3; 1986bptesty(_,_) -> 1987 error. 1988 1989bptest(B,A,_C) when length(B) =:= A -> 1990 1; 1991bptest(B,A,C) when binary_part(B,{A,C}) =:= <<2>> -> 1992 1; 1993bptest(B,A,C) when erlang:binary_part(B,A,C) =:= <<1>> -> 1994 2; 1995bptest(B,A,C) when erlang:binary_part(B,{A,C}) =:= <<3,3>> -> 1996 3; 1997bptest(_,_,_) -> 1998 error. 1999 2000-define(FAILING(C), 2001 if 2002 C -> ct:fail(should_fail); 2003 true -> ok 2004 end, 2005 if 2006 true, C -> ct:fail(should_fail); 2007 true -> ok 2008 end). 2009 2010bad_constants(Config) when is_list(Config) -> 2011 ?FAILING(false), 2012 ?FAILING([]), 2013 ?FAILING([a]), 2014 ?FAILING([Config]), 2015 ?FAILING({a,b}), 2016 ?FAILING({a,Config}), 2017 ?FAILING(<<1>>), 2018 ?FAILING(42), 2019 ?FAILING(3.14), 2020 ok. 2021 2022bad_guards(Config) when is_list(Config) -> 2023 if erlang:float(self()); true -> ok end, 2024 2025 fc(catch bad_guards_1(1, [])), 2026 fc(catch bad_guards_1(1, [2])), 2027 fc(catch bad_guards_1(atom, [2])), 2028 2029 fc(catch bad_guards_2(#{a=>0,b=>0}, [])), 2030 fc(catch bad_guards_2(#{a=>0,b=>0}, [x])), 2031 fc(catch bad_guards_2(not_a_map, [x])), 2032 fc(catch bad_guards_2(42, [x])), 2033 2034 fc(catch bad_guards_3(#{a=>0,b=>0}, [])), 2035 fc(catch bad_guards_3(#{a=>0,b=>0}, [x])), 2036 fc(catch bad_guards_3(not_a_map, [x])), 2037 fc(catch bad_guards_3(42, [x])), 2038 2039 fc(catch bad_guards_4()), 2040 2041 ok. 2042 2043%% beam_bool used to produce GC BIF instructions whose 2044%% Live operands included uninitialized registers. 2045 2046bad_guards_1(X, [_]) when {{X}}, -X -> 2047 ok. 2048 2049bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) -> 2050 ok. 2051 2052%% beam_type used to produce an GC BIF instruction whose Live operand 2053%% included uninitialized registers. 2054 2055bad_guards_3(M, [_]) when is_map(M) andalso M#{a := 0, b => 0}, length(M) -> 2056 ok. 2057 2058%% v3_codegen would generate a jump to the failure label, but 2059%% without initializing x(0). The code at the failure label expected 2060%% x(0) to be initialized. 2061 2062bad_guards_4() when not (error#{}); {not 0.0} -> freedom. 2063 2064%% Building maps in a guard in a 'catch' would crash v3_codegen. 2065 2066guard_in_catch(_Config) -> 2067 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{}), 2068 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{a=>b}), 2069 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(atom), 2070 2071 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{}), 2072 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{a=>b}), 2073 {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(atom), 2074 2075 {'EXIT',{if_clause,_}} = (catch do_guard_in_catch_map_3()), 2076 2077 {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(42), 2078 {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(<<1,2,3>>), 2079 {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(atom), 2080 {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(#{}), 2081 2082 ok. 2083 2084do_guard_in_catch_map_1(From) -> 2085 catch 2086 if 2087 From#{[] => sufficient} -> 2088 saint 2089 end. 2090 2091do_guard_in_catch_map_2(From) -> 2092 catch 2093 if 2094 From#{From => sufficient} -> 2095 saint 2096 end. 2097 2098do_guard_in_catch_map_3() -> 2099 try 2100 if [] -> solo end 2101 catch 2102 Friendly when Friendly#{0 => []} -> minutes 2103 after 2104 membership 2105 end. 2106 2107do_guard_in_catch_bin(From) -> 2108 %% Would not crash v3_codegen, but there would be an unnecessary 2109 %% 'move' to a Y register. 2110 catch 2111 if 2112 <<From:32>> -> 2113 saint 2114 end. 2115 2116%%% 2117%%% The beam_bool pass has been eliminated. Here are the tests from 2118%%% beam_bool_SUITE. 2119%%% 2120 2121beam_bool_SUITE(_Config) -> 2122 before_and_inside_if(), 2123 scotland(), 2124 y_registers(), 2125 protected(), 2126 maps(), 2127 ok. 2128 2129before_and_inside_if() -> 2130 no = before_and_inside_if([a], [b], delete), 2131 no = before_and_inside_if([a], [b], x), 2132 no = before_and_inside_if([a], [], delete), 2133 no = before_and_inside_if([a], [], x), 2134 no = before_and_inside_if([], [], delete), 2135 yes = before_and_inside_if([], [], x), 2136 yes = before_and_inside_if([], [b], delete), 2137 yes = before_and_inside_if([], [b], x), 2138 2139 {ch1,ch2} = before_and_inside_if_2([a], [b], blah), 2140 {ch1,ch2} = before_and_inside_if_2([a], [b], xx), 2141 {ch1,ch2} = before_and_inside_if_2([a], [], blah), 2142 {ch1,ch2} = before_and_inside_if_2([a], [], xx), 2143 {no,no} = before_and_inside_if_2([], [b], blah), 2144 {no,no} = before_and_inside_if_2([], [b], xx), 2145 {ch1,no} = before_and_inside_if_2([], [], blah), 2146 {no,ch2} = before_and_inside_if_2([], [], xx), 2147 ok. 2148 2149%% Thanks to Simon Cornish and Kostis Sagonas. 2150%% Used to crash beam_bool. 2151before_and_inside_if(XDo1, XDo2, Do3) -> 2152 Do1 = (XDo1 =/= []), 2153 Do2 = (XDo2 =/= []), 2154 if 2155 %% This expression occurs in a try/catch (protected) 2156 %% block, which cannot refer to variables outside of 2157 %% the block that are boolean expressions. 2158 Do1 =:= true; 2159 Do1 =:= false, Do2 =:= false, Do3 =:= delete -> 2160 no; 2161 true -> 2162 yes 2163 end. 2164 2165%% Thanks to Simon Cornish. 2166%% Used to generate code that would not set {y,0} on 2167%% all paths before its use (and therefore fail 2168%% validation by the beam_validator). 2169before_and_inside_if_2(XDo1, XDo2, Do3) -> 2170 Do1 = (XDo1 =/= []), 2171 Do2 = (XDo2 =/= []), 2172 CH1 = if Do1 == true; 2173 Do1 == false,Do2==false,Do3 == blah -> 2174 ch1; 2175 true -> 2176 no 2177 end, 2178 CH2 = if Do1 == true; 2179 Do1 == false,Do2==false,Do3 == xx -> 2180 ch2; 2181 true -> 2182 no 2183 end, 2184 {CH1,CH2}. 2185 2186 2187%% beam_bool would remove the initialization of {y,0}. 2188%% (Thanks to Thomas Arts and QuickCheck.) 2189 2190scotland() -> 2191 million = do_scotland(placed), 2192 {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)), 2193 {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)), 2194 {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)), 2195 ok. 2196 2197do_scotland(Echo) -> 2198 found(case Echo of 2199 Echo when true; Echo, Echo, Echo -> 2200 Echo; 2201 echo -> 2202 [] 2203 end, 2204 Echo = placed). 2205 2206found(_, _) -> million. 2207 2208 2209%% ERL-143: beam_bool could not handle Y registers as a destination. 2210y_registers() -> 2211 {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)), 2212 {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)), 2213 2214 {not_ok,true} = potter([]), 2215 {ok,false} = potter([{encoding,any}]), 2216 2217 ok. 2218 2219%% Thanks to Quickcheck. 2220baker(Baker) -> 2221 (valentine == Baker) + 2222 case Baker of 2223 Baker when Baker; Baker -> 2224 Baker; 2225 Baker -> 2226 [] 2227 end. 2228 2229%% Thanks to Jose Valim. 2230potter(Modes) -> 2231 Raw = lists:keyfind(encoding, 1, Modes) == false, 2232 Final = case Raw of 2233 X when X == false; X == nil -> ok; 2234 _ -> not_ok 2235 end, 2236 {Final,Raw}. 2237 2238protected() -> 2239 {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)), 2240 2241 {{true}} = welcome({perfect, true}), 2242 {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})), 2243 ok. 2244 2245photographs({_Violation, surprise, Deep}, opinions) -> 2246 {if 2247 0; "here", Deep -> 2248 Deep = Deep 2249 end}. 2250 2251welcome({perfect, Profit}) -> 2252 if 2253 Profit, Profit, Profit; 0 -> 2254 {id({Profit})} 2255 end. 2256 2257maps() -> 2258 ok = evidence(#{0 => 42}). 2259 2260%% Cover handling of put_map in in split_block_label_used/2. 2261evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} -> 2262 ok. 2263 2264%% Call this function to turn off constant propagation. 2265id(I) -> I. 2266 2267check(F, Result) -> 2268 case F() of 2269 Result -> ok; 2270 Other -> 2271 io:format("Expected: ~p\n", [Result]), 2272 io:format(" Got: ~p\n", [Other]), 2273 ct:fail(check_failed) 2274 end. 2275 2276fc({'EXIT',{function_clause,_}}) -> ok; 2277fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= guard_inline_SUITE -> ok.