1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2001-2020. 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("syntax_tools/include/merl.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,
35         generated_combinations/1,literal_type_tests/1,
36	 basic_andalso_orelse/1,traverse_dcd/1,
37	 check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
38	 bad_constants/1,bad_guards/1,
39         guard_in_catch/1,beam_bool_SUITE/1,
40         repeated_type_tests/1,use_after_branch/1]).
41
42suite() -> [{ct_hooks,[ts_install_cth]}].
43
44all() ->
45    slow_group() ++ [{group,p}].
46
47groups() ->
48    [{p,[parallel],
49      [misc,const_cond,basic_not,complex_not,nested_nots,
50       semicolon,complex_semicolon,comma,or_guard,
51       more_or_guards,complex_or_guards,and_guard,xor_guard,
52       more_xor_guards,build_in_guard,
53       old_guard_tests,complex_guard,gbif,
54       t_is_boolean,is_function_2,tricky,
55       rel_ops,rel_op_combinations,
56       basic_andalso_orelse,traverse_dcd,
57       check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
58       bad_constants,bad_guards,guard_in_catch,beam_bool_SUITE,
59       repeated_type_tests,use_after_branch]},
60     {slow,[],[literal_type_tests,generated_combinations]}].
61
62init_per_suite(Config) ->
63    test_lib:recompile(?MODULE),
64    Config.
65
66end_per_suite(_Config) ->
67    ok.
68
69init_per_group(_GroupName, Config) ->
70    Config.
71
72end_per_group(_GroupName, Config) ->
73    Config.
74
75slow_group() ->
76    case ?MODULE of
77	guard_SUITE ->
78            %% Canononical module name. Run slow cases.
79            [{group,slow}];
80        _ ->
81            %% Cloned module. Don't run.
82            []
83    end.
84
85misc(Config) when is_list(Config) ->
86    42 = case id(42) of
87	     X when -X -> ok;
88	     X -> X
89	 end,
90    {a,b,c} = misc_1([{{a,b,c}},{[4]},{[3]},{-2}]),
91    none = misc_1([{{a,b,c}},{[4]},{[3]},{-3}]),
92    none = misc_1([{{a,b,c}},{[4]},{[7]},{-2}]),
93    none = misc_1([{{a,b,c}},{[4]},{[3]},{[1,2,3]}]),
94
95    {ok,buf,<<>>} = get_data({o,true,raw}, 0, buf),
96    {ok,buf,<<>>} = get_data({o,true,raw}, 42, buf),
97    {ok,buf,<<>>} = get_data({o,false,raw}, 0, buf),
98    error = get_data({o,false,raw}, 42, buf),
99    {ok,buf,<<>>} = get_data({o,true,0}, 0, buf),
100    {ok,buf,<<>>} = get_data({o,true,0}, 42, buf),
101    {ok,buf,<<>>} = get_data({o,false,0}, 0, buf),
102    error = get_data({o,false,0}, 42, buf),
103
104    relief = misc_2(0),
105    error = misc_2(1),
106    error = misc_2(true),
107
108    if
109	is_integer(Config) =/= true ->
110	    ok
111    end,
112
113    true = misc_3(1, 0),
114    true = misc_3(0, 0),
115    false = misc_3(0, 2),
116
117    %% Abuse of boolean values.
118
119    Zero = id(0),
120    One = id(1),
121    ok = if (Zero == 0) > false -> ok end,
122    ok = if (Zero == 0) =:= (One == 1) -> ok end,
123    ok = if (Zero == 0) =:= (One == 1) -> ok end,
124    ok = if is_atom(Zero > One) -> ok end,
125    error = if abs(Zero > One) -> ok; true -> error end,
126    ok = if is_integer(Zero) >= is_integer(One) -> ok end,
127
128    ok.
129
130misc_1([{W},{X},{Y},{Z}]) ->
131	      if
132	X > Y andalso abs(Z) =:= 2 ->
133	    id(W);
134	true ->
135	    none
136    end.
137
138misc_2(0) -> relief;
139misc_2(Adapter = 1) when Adapter -> franklin;
140misc_2(_) -> error.
141
142misc_3(LenUp, LenDw) ->
143    if
144	%% Cover handling of #k_alt{}.
145	LenUp >= 1 orelse ((LenDw >= 2) xor true) -> true;
146	true -> false
147    end.
148
149get_data({o,Active,Raw}, BytesToRead, Buffer)
150  when Raw =:= raw; Raw =:= 0 ->
151    if
152	Active =/= false orelse BytesToRead =:= 0  ->
153	    {ok,Buffer,<<>>};
154	true ->
155	    error
156    end.
157
158const_cond(Config) when is_list(Config) ->
159    ok = const_cond({}, 0),
160    ok = const_cond({a}, 1),
161    error = const_cond({a,b}, 3),
162    error = const_cond({a}, 0),
163    error = const_cond({a,b}, 1),
164    ok.
165
166const_cond(T, Sz) ->
167    case T of
168	_X when false -> never;
169	_X when is_tuple(T), eq == eq, tuple_size(T) == Sz -> ok;
170	_X when is_tuple(T), eq == leq, tuple_size(T) =< Sz -> ok;
171	_X -> error
172    end.
173
174basic_not(Config) when is_list(Config) ->
175    True = id(true),
176    False = id(false),
177    Glurf = id(glurf),
178    A = id(5),
179    B = id(37.5),
180    C = id(-1),
181    D = id(5),
182    ATuple = {False,True,Glurf},
183
184    check(fun() -> if not false -> ok; true -> error end end, ok),
185    check(fun() -> if not true -> ok; true -> error end end, error),
186    check(fun() -> if not False -> ok; true -> error end end, ok),
187    check(fun() -> if not True -> ok; true -> error end end, error),
188
189    check(fun() -> if A > B -> gt; A < B -> lt; A == B -> eq end end, lt),
190    check(fun() -> if A > C -> gt; A < C -> lt; A == C -> eq end end, gt),
191    check(fun() -> if A > D -> gt; A < D -> lt; A == D -> eq end end, eq),
192
193    check(fun() -> if not (7 > 453) -> le; not (7 < 453) -> ge;
194		      not (7 == 453) -> ne; true -> eq end end, le),
195    check(fun() -> if not (7 > -8) -> le; not (7 < -8) -> ge;
196		      not (7 == -8) -> ne; true -> eq end end, ge),
197    check(fun() -> if not (7 > 7) -> le; not (7 < 7) -> ge;
198		      not (7 == 7) -> ne; true -> eq end end, le),
199
200    check(fun() -> if not (A > B) -> le; not (A < B) -> ge;
201		      not (A == B) -> ne; true -> eq end end, le),
202    check(fun() -> if not (A > C) -> le; not (A < C) -> ge;
203		      not (A == C) -> ne; true -> eq end end, ge),
204    check(fun() -> if not (A > D) -> le; not (A < D) -> ge;
205		      not (A == D) -> ne; true -> eq end end, le),
206
207    check(fun() -> if not element(1, ATuple) -> ok; true -> error end end, ok),
208    check(fun() -> if not element(2, ATuple) -> ok; true -> error end end, error),
209    check(fun() -> if not element(3, ATuple) -> ok; true -> error end end, error),
210
211    check(fun() -> if not glurf -> ok; true -> error end end, error),
212    check(fun() -> if not Glurf -> ok; true -> error end end, error),
213
214    check(fun() -> if not (not true) -> broken end end, broken),
215
216    check(fun() -> if not (True xor True) -> ok end end, ok),
217    check(fun() -> if not (True xor False) -> ok;
218		      true -> error end end, error),
219
220    check(fun() -> if not (True =:= true) -> ok; true -> error end end, error),
221    check(fun() -> if not (False =:= true) -> ok; true -> error end end, ok),
222    check(fun() -> if not (Glurf =:= true) -> ok; true -> error end end, ok),
223
224    ok.
225
226complex_not(Config) when is_list(Config) ->
227    ATuple = id({false,true,gurka}),
228    check(fun() -> if not(element(1, ATuple)) -> ok; true -> error end end, ok),
229    check(fun() -> if not(element(2, ATuple)) -> ok; true -> error end end, error),
230
231    check(fun() -> if not(element(3, ATuple) == gurka) -> ok;
232		      true -> error end end, error),
233    check(fun() -> if not(element(3, ATuple) =/= gurka) -> ok;
234		      true -> error end end, ok),
235
236    check(fun() -> if {a,not(element(2, ATuple))} == {a,false} -> ok;
237		      true -> error end end, ok),
238    check(fun() -> if {a,not(element(1, ATuple))} == {a,false} -> ok;
239		      true -> error end end, error),
240
241    check(fun() -> if not(element(1, ATuple) or element(3, ATuple)) -> ok;
242		      true -> error end end, error),
243
244    %% orelse
245    check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok;
246		      true -> error end end, error),
247
248    %% complex_not_1/4
249    ok = complex_not_1(1, 1, 1, a),
250    error = complex_not_1(1, 1, 1, []),
251    error = complex_not_1(1, 1, 3, a),
252    error = complex_not_1(1, 1, 3, []),
253    error = complex_not_1(1, 2, 1, a),
254    error = complex_not_1(1, 2, 1, []),
255    error = complex_not_1(1, 2, 3, a),
256    error = complex_not_1(1, 2, 3, []),
257
258    %% complex_not_2/4
259    ok = complex_not_2(1, 2, 0, x),
260    error = complex_not_2(1, 2, 0, []),
261    error = complex_not_2(1, 2, 3, x),
262    error = complex_not_2(1, 2, 3, []),
263    error = complex_not_2(1, 1, 0, x),
264    error = complex_not_2(1, 1, 0, []),
265    error = complex_not_2(1, 1, 3, x),
266    error = complex_not_2(1, 1, 3, []),
267
268    ok.
269
270complex_not_1(A, B, C, D) ->
271    Res = complex_not_1a(A, B, C, D),
272    Res = complex_not_1b(A, B, C, D).
273
274complex_not_1a(A, B, C, D)
275  when (not (A < B)) andalso (not (B < C)) andalso (not is_list(D)) ->
276    ok;
277complex_not_1a(_, _, _, _) ->
278    error.
279
280complex_not_1b(A, B, C, D)
281  when (not (A < B)) and (not (B < C)) and (not is_list(D)) ->
282    ok;
283complex_not_1b(_, _, _, _) ->
284    error.
285
286complex_not_2(A, B, C, D) ->
287    Res = complex_not_2a(A, B, C, D),
288    Res = complex_not_2b(A, B, C, D).
289
290complex_not_2a(A, B, C, D)
291  when A < B andalso not (B < C) andalso not is_list(D) ->
292    ok;
293complex_not_2a(_, _, _, _) ->
294    error.
295
296complex_not_2b(A, B, C, D)
297  when A < B, not (B < C), not is_list(D) ->
298    ok;
299complex_not_2b(_, _, _, _) ->
300    error.
301
302nested_nots(Config) when is_list(Config) ->
303    true = nested_not_1(0, 0),
304    true = nested_not_1(0, 1),
305    true = nested_not_1(a, b),
306    true = nested_not_1(10, 0),
307    false = nested_not_1(z, a),
308    false = nested_not_1(3.4, {anything,goes}),
309    false = nested_not_1(3.4, atom),
310    true = nested_not_1(3.0, [list]),
311
312    true = nested_not_2(false, false, 42),
313    true = nested_not_2(false, true, 42),
314    true = nested_not_2(true, false, 42),
315    true = nested_not_2(true, true, 42),
316    true = nested_not_2(false, false, atom),
317    false = nested_not_2(false, true, atom),
318    false = nested_not_2(true, false, atom),
319    false = nested_not_2(true, true, atom),
320    ok.
321
322nested_not_1(X, Y) ->
323    Res = nested_not_1a(X, Y),
324    Res = nested_not_1b(X, Y).
325
326nested_not_1a(X, Y) when not (((X>Y) or not(is_atom(X))) and
327			     (is_atom(Y) or (X==3.4))) ->
328    true;
329nested_not_1a(_, _) ->
330    false.
331
332nested_not_1b(X, Y) when not (((X>Y) orelse not(is_atom(X))) andalso
333			     (is_atom(Y) orelse (X==3.4))) ->
334    true;
335nested_not_1b(_, _) ->
336    false.
337
338nested_not_2(X, Y, Z) ->
339    Res = nested_not_2a(X, Y, Z, true),
340    Res = nested_not_2b(X, Y, Z, true).
341
342nested_not_2a(X, Y, Z, True)
343  when not(True and not((not(X) and not(Y)) or not(is_atom(Z)))) ->
344    true;
345nested_not_2a(_, _, _, _) ->
346    false.
347
348nested_not_2b(X, Y, Z, True)
349  when not(True andalso not((not(X) andalso not(Y)) orelse not(is_atom(Z)))) ->
350    true;
351nested_not_2b(_, _, _, _) ->
352    false.
353
354semicolon(Config) when is_list(Config) ->
355
356    %% True/false combined using ';' (literal atoms).
357
358    check(fun() -> if true; false -> ok end end, ok),
359    check(fun() -> if false; true -> ok end end, ok),
360    check(fun() -> if true; true -> ok end end, ok),
361    check(fun() -> if false; false -> ok; true -> error end end, error),
362    check(fun() ->
363		  {'EXIT',{if_clause,_}} = (catch if false; false -> ok end),
364		  exit
365	  end, exit),
366
367    %% True/false combined used ';'.
368
369    True = id(true),
370    False = id(false),
371
372    check(fun() -> if True; False -> ok end end, ok),
373    check(fun() -> if False; True -> ok end end, ok),
374    check(fun() -> if True; True -> ok end end, ok),
375    check(fun() -> if False; False -> ok; true -> error end end, error),
376    check(fun() ->
377		  {'EXIT',{if_clause,_}} = (catch if False; False -> ok end),
378		  exit
379	  end, exit),
380
381    %% Combine true/false with a non-boolean value.
382    Glurf = id(glurf),
383
384
385    check(fun() -> if True; Glurf -> ok end end, ok),
386    check(fun() -> if Glurf; True -> ok end end, ok),
387    check(fun() -> if Glurf; Glurf -> ok; true -> error end end, error),
388    check(fun() -> if False; Glurf -> ok; true -> error end end, error),
389    check(fun() -> if Glurf; False -> ok; true -> error end end, error),
390    check(fun() ->
391		  {'EXIT',{if_clause,_}} = (catch if Glurf; Glurf -> ok end),
392		  exit
393	  end, exit),
394
395    %% Combine true/false with errors.
396
397    ATuple = id({false,true,gurka}),
398
399    check(fun() -> if True; element(42, ATuple) -> ok end end, ok),
400    check(fun() -> if element(42, ATuple); True -> ok end end, ok),
401    check(fun() -> if element(42, ATuple); element(42, ATuple) -> ok;
402		      true -> error end end, error),
403    check(fun() -> if False; element(42, ATuple) -> ok;
404		      true -> error end end, error),
405    check(fun() -> if element(42, ATuple);
406		      False -> ok; true -> error end end, error),
407    check(fun() ->
408		  {'EXIT',{if_clause,_}} =
409		      (catch if element(42, ATuple);
410				element(42, ATuple) -> ok end),
411		  exit
412	  end, exit),
413
414    ok.
415
416complex_semicolon(Config) when is_list(Config) ->
417    ok = csemi1(int, {blurf}),
418    ok = csemi1(string, {blurf}),
419    ok = csemi1(float, [a]),
420    error = csemi1(35, 42),
421
422    %% 2
423    ok = csemi2({}, {a,b,c}),
424    ok = csemi2({1,3.5}, {a,b,c}),
425    ok = csemi2(dum, {a,b,c}),
426
427    ok = csemi2({45,-19.3}, {}),
428    ok = csemi2({45,-19.3}, {dum}),
429    ok = csemi2({45,-19.3}, {dum,dum}),
430
431    error = csemi2({45}, {dum}),
432    error = csemi2([], {dum}),
433    error = csemi2({dum}, []),
434    error = csemi2([], []),
435
436    %% 3
437    csemi3(fun csemi3a/4),
438    csemi3(fun csemi3b/4),
439    csemi3(fun csemi3c/4),
440
441    %% 4
442    csemi4(fun csemi4a/4),
443    csemi4(fun csemi4b/4),
444    csemi4(fun csemi4c/4),
445    csemi4(fun csemi4d/4),
446
447    %% 4, 'orelse' instead of 'or'
448    csemi4_orelse(fun csemi4_orelse_a/4),
449    csemi4_orelse(fun csemi4_orelse_b/4),
450    csemi4_orelse(fun csemi4_orelse_c/4),
451    csemi4_orelse(fun csemi4_orelse_d/4),
452
453    %% 5
454    error = csemi5(0, 0),
455    ok = csemi5(5, 0),
456    ok = csemi5(4, -4),
457    ok = csemi5(10, -4),
458
459    %% 6
460    error = csemi6({a}, 0),
461    ok = csemi6({a,b}, 0),
462    ok = csemi6({}, 3),
463    ok = csemi6({a,b,c}, 3),
464
465    %% 7
466    error = csemi7(#{a=>1}, 1, 0),
467    error = csemi7(<<>>, 1, 0),
468    ok = csemi7(#{a=>1}, 3, 0),
469    ok = csemi7(#{a=>1}, 0, 3),
470    ok = csemi7(#{a=>1}, 3, 3),
471    ok = csemi7(#{a=>1, b=>3}, 0, 0),
472
473    %% 8: Make sure that funs cannot be copied into guards.
474    ok = csemi8(true),
475    error = csemi8(false),
476    error = csemi8(42),
477
478    ok.
479
480csemi1(Type, Val) when is_list(Val), Type == float;
481		       Type == int; Type == string -> ok;
482csemi1(_, _) -> error.
483
484csemi2(A, B) when tuple_size(A) > 1; tuple_size(B) > 2 -> ok;
485csemi2(_, _) -> error.
486
487csemi3(Csemi3) ->
488    ok = Csemi3({}, {a,b,c}, [0], [0]),
489    ok = Csemi3({1,3.5}, {a,b,c}, -1, -1),
490    ok = Csemi3(dum, {a,b,c}, 0.0, 0.0),
491    ok = Csemi3(dum, {c}, b, a),
492    ok = Csemi3(dum, <<1,2,3>>, 0.0, 0.0),
493    ok = Csemi3(<<3.5/float>>, {a,b,c}, -1, -1),
494
495    ok = Csemi3({45,-19.3}, {}, [], []),
496    ok = Csemi3({45,-19.3}, {dum}, 42, 42),
497    ok = Csemi3({45,-19.3}, {dum,dum}, 33, 33),
498
499    ok = Csemi3({45}, {dum}, 1.0, 0),
500    ok = Csemi3([a], {dum}, 1.0, 0),
501    ok = Csemi3({dum}, [], 1.0, 0),
502    ok = Csemi3([], [], 1.0, 0),
503    ok = Csemi3(blurf, {dum}, 1.0, 0),
504    ok = Csemi3({a}, blurf, 1.0, 0),
505    ok = Csemi3([a], [dum], 1.0, 0),
506    ok = Csemi3({dum}, [], 1.0, 0),
507    ok = Csemi3([], [], 1.0, 0),
508
509    error = Csemi3({45}, {dum}, 0, 0),
510    error = Csemi3([a], {dum}, 0, 0),
511    error = Csemi3({dum}, [], 0, 0),
512    error = Csemi3([], [], 0, 0),
513
514    ok.
515
516csemi3a(A, B, X, Y) when X > Y; size(A) > 1; size(B) > 2 -> ok;
517csemi3a(_, _, _, _) -> error.
518
519csemi3b(A, B, X, Y) when size(A) > 1; X > Y; size(B) > 2 -> ok;
520csemi3b(_, _, _, _) -> error.
521
522csemi3c(A, B, X, Y) when size(A) > 1; size(B) > 2; X > Y -> ok;
523csemi3c(_, _, _, _) -> error.
524
525
526csemi4(Test) ->
527    ok = Test({a,b}, 2, {c,d}, 2),
528    ok = Test({1,2,3}, 0, [], 0),
529    ok = Test({}, 2, blurf, 0),
530    ok = Test({}, 2, {1}, 2),
531
532    error = Test([], 4, {}, 0),
533    error = Test({}, 0, [a,b], 4),
534    error = Test({}, 0, [a,b], 0),
535    error = Test([], 0, {}, 0),
536    error = Test({}, 0, {}, 0),
537
538    ok.
539
540csemi4a(A, X, B, Y) when (tuple_size(A) > 1) or (X > 1);
541			 (tuple_size(B) > 1) or (Y > 1) -> ok;
542csemi4a(_, _, _, _) -> error.
543
544csemi4b(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
545			 (tuple_size(B) > 1) or (Y > 1) -> ok;
546csemi4b(_, _, _, _) -> error.
547
548csemi4c(A, X, B, Y) when (tuple_size(A) > 1) or (X > 1);
549			 (Y > 1) or (tuple_size(B) > 1) -> ok;
550csemi4c(_, _, _, _) -> error.
551
552csemi4d(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
553			 (Y > 1) or (tuple_size(B) > 1) -> ok;
554csemi4d(_, _, _, _) -> error.
555
556
557csemi4_orelse(Test) ->
558    ok = Test({a,b}, 2, {c,d}, 2),
559    ok = Test({1,2,3}, 0, [], 0),
560    ok = Test({}, 2, blurf, 0),
561    ok = Test({}, 2, {1}, 2),
562
563    error = Test([], 1, {}, 0),
564
565    ok.
566
567csemi4_orelse_a(A, X, B, Y) when (tuple_size(A) > 1) orelse (X > 1);
568			 (tuple_size(B) > 1) orelse (Y > 1) -> ok;
569csemi4_orelse_a(_, _, _, _) -> error.
570
571csemi4_orelse_b(A, X, B, Y) when (X > 1) orelse (tuple_size(A) > 1);
572			 (tuple_size(B) > 1) orelse (Y > 1) -> ok;
573csemi4_orelse_b(_, _, _, _) -> error.
574
575csemi4_orelse_c(A, X, B, Y) when (tuple_size(A) > 1) orelse (X > 1);
576                           (Y > 1) orelse (tuple_size(B) > 1) -> ok;
577csemi4_orelse_c(_, _, _, _) -> error.
578
579csemi4_orelse_d(A, X, B, Y) when (X > 1) or (tuple_size(A) > 1);
580			 (Y > 1) or (tuple_size(B) > 1) -> ok;
581csemi4_orelse_d(_, _, _, _) -> error.
582
583csemi5(A, B) when hd([A+B]) > 1; abs(B) > 2 -> ok;
584csemi5(_, _) -> error.
585
586csemi6(A, B) when hd([tuple_size(A)]) > 1; abs(B) > 2 -> ok;
587csemi6(_, _) -> error.
588
589csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok;
590csemi7(_, _, _) -> error.
591
592csemi8(Together) ->
593  case fun csemi8/1 of
594      Typically when Together; Typically, Together -> ok;
595      _ -> error
596  end.
597
598
599comma(Config) when is_list(Config) ->
600
601    %% ',' combinations of literal true/false.
602
603    check(fun() -> if true, false -> ok; true -> error end end, error),
604    check(fun() -> if false, true -> ok; true -> error end end, error),
605    check(fun() -> if true, true -> ok end end, ok),
606    check(fun() -> if false, false -> ok; true -> error end end, error),
607    check(fun() ->
608		  {'EXIT',{if_clause,_}} =
609		      (catch if true, false -> ok;
610				false, true -> ok;
611				false, false -> ok
612			     end),
613		  exit
614	  end, exit),
615
616    %% ',' combinations of true/false in variables.
617
618    True = id(true),
619    False = id(false),
620
621    check(fun() -> if True, False -> ok; true -> error end end, error),
622    check(fun() -> if False, True -> ok; true -> error end end, error),
623    check(fun() -> if True, True -> ok end end, ok),
624    check(fun() -> if False, False -> ok; true -> error end end, error),
625    check(fun() ->
626		  {'EXIT',{if_clause,_}} =
627		      (catch if True, False -> ok;
628				False, True -> ok;
629				False, False -> ok
630			     end),
631		  exit
632	  end, exit),
633
634    %% ',' combinations of true/false, and non-boolean in variables.
635
636    Glurf = id(glurf),
637
638    check(fun() -> if True, Glurf -> ok; true -> error end end, error),
639    check(fun() -> if Glurf, True -> ok; true -> error end end, error),
640    check(fun() -> if True, True -> ok end end, ok),
641    check(fun() -> if Glurf, Glurf -> ok; true -> error end end, error),
642    check(fun() ->
643		  {'EXIT',{if_clause,_}} =
644		      (catch if True, Glurf -> ok;
645				Glurf, True -> ok;
646				Glurf, Glurf -> ok
647			     end),
648		  exit
649	  end, exit),
650
651    %% ',' combinations of true/false with errors.
652    ATuple = id({a,b,c}),
653
654    check(fun() -> if True, element(42, ATuple) -> ok;
655		      true -> error end end, error),
656    check(fun() -> if element(42, ATuple), True -> ok;
657		      true -> error end end, error),
658    check(fun() -> if True, True -> ok end end, ok),
659    check(fun() -> if element(42, ATuple), element(42, ATuple) -> ok;
660		      true -> error end end, error),
661    check(fun() ->
662		  {'EXIT',{if_clause,_}} =
663		      (catch if True, element(42, ATuple) -> ok;
664				element(42, ATuple), True -> ok;
665				element(42, ATuple), element(42, ATuple) -> ok
666			     end),
667		  exit
668	  end, exit),
669
670    ok.
671
672or_guard(Config) when is_list(Config) ->
673    True = id(true),
674    False = id(false),
675    Glurf = id(glurf),
676
677    %% 'or' combinations of literal true/false.
678    check(fun() -> if true or false -> ok end end, ok),
679    check(fun() -> if false or true -> ok end end, ok),
680    check(fun() -> if true or true -> ok end end, ok),
681    check(fun() -> if false or false -> ok; true -> error end end, error),
682
683    check(fun() -> if glurf or true -> ok; true -> error end end, error),
684    check(fun() -> if true or glurf -> ok; true -> error end end, error),
685    check(fun() -> if glurf or glurf -> ok; true -> error end end, error),
686
687    check(fun() ->
688		  {'EXIT',{if_clause,_}} = (catch if false or false -> ok end),
689		  exit
690	  end, exit),
691
692
693    %% 'or' combinations using variables containing true/false.
694    check(fun() -> if True or False -> ok end end, ok),
695    check(fun() -> if False or True -> ok end end, ok),
696    check(fun() -> if True or True -> ok end end, ok),
697    check(fun() -> if False or False -> ok; true -> error end end, error),
698
699    check(fun() -> if True or Glurf -> ok; true -> error end end, error),
700    check(fun() -> if Glurf or True -> ok; true -> error end end, error),
701    check(fun() -> if Glurf or Glurf -> ok; true -> error end end, error),
702
703    check(fun() ->
704		  {'EXIT',{if_clause,_}} = (catch if False or False -> ok end),
705		  exit
706	  end, exit),
707
708    ok.
709
710more_or_guards(Config) when is_list(Config) ->
711    True = id(true),
712    False = id(false),
713    ATuple = id({false,true,gurka}),
714
715    check(fun() ->
716		  if element(42, ATuple) or False -> ok;
717		     true -> error end
718	  end, error),
719
720    check(fun() ->
721		  if False or element(42, ATuple) -> ok;
722		     true -> error end
723	  end, error),
724
725    check(fun() ->
726		  if element(18, ATuple) or element(42, ATuple) -> ok;
727		     true -> error end
728	  end, error),
729
730    check(fun() ->
731		  if True or element(42, ATuple) -> ok;
732		     true -> error end
733	  end, error),
734
735    check(fun() ->
736		  if element(42, ATuple) or True -> ok;
737		     true -> error end
738	  end, error),
739
740    check(fun() ->
741		  if element(1, ATuple) or element(42, ATuple) or True -> ok;
742		     true -> error end
743	  end, error),
744
745    check(fun() ->
746		  if element(1, ATuple) or True or element(42, ATuple) -> ok;
747		     true -> error end
748	  end, error),
749
750    check(fun() ->
751		  if
752		      (<<False:8>> == <<0>>) or element(2, ATuple) -> ok;
753		      true -> error end
754	  end, error),
755
756    check(fun() ->
757		  if
758		      element(2, ATuple) or (<<True:8>> == <<1>>) -> ok;
759		      true -> error end
760	  end, error),
761
762    check(fun() ->
763		  if element(2, ATuple) or element(42, ATuple) -> ok;
764		     true -> error end
765	  end, error),
766
767    check(fun() ->
768		  if
769		      element(1, ATuple) or
770		      element(2, ATuple) or
771		      element(19, ATuple) -> ok;
772		      true -> error end
773	  end, error),
774    ok.
775
776complex_or_guards(Config) when is_list(Config) ->
777    %% complex_or_1/2
778    ok = complex_or_1({a,b,c,d}, {1,2,3}),
779    ok = complex_or_1({a,b,c,d}, {1}),
780    ok = complex_or_1({a}, {1,2,3}),
781    error = complex_or_1({a}, {1}),
782
783    error = complex_or_1(1, 2),
784    error = complex_or_1([], {a,b,c,d}),
785    error = complex_or_1({a,b,c,d}, []),
786
787
788    %% complex_or_2/1
789    ok = complex_or_2({true,{}}),
790    ok = complex_or_2({false,{a}}),
791    ok = complex_or_2({false,{a,b,c}}),
792    ok = complex_or_2({true,{a,b,c,d}}),
793
794    error = complex_or_2({blurf,{a,b,c}}),
795
796    error = complex_or_2({true}),
797    error = complex_or_2({true,no_tuple}),
798    error = complex_or_2({true,[]}),
799
800    %% complex_or_3/2
801    ok = complex_or_3({true}, {}),
802    ok = complex_or_3({false}, {a}),
803    ok = complex_or_3({false}, {a,b,c}),
804    ok = complex_or_3({true}, {a,b,c,d}),
805    ok = complex_or_3({false}, <<1,2,3>>),
806    ok = complex_or_3({true}, <<1,2,3,4>>),
807
808    error = complex_or_3(blurf, {a,b,c}),
809
810    error = complex_or_3({false}, <<1,2,3,4>>),
811    error = complex_or_3([], <<1,2>>),
812    error = complex_or_3({true}, 45),
813    error = complex_or_3(<<>>, <<>>),
814
815    %% complex_or_4/2
816    ok = complex_or_4(<<1,2,3>>, {true}),
817    ok = complex_or_4(<<1,2,3>>, {false}),
818    ok = complex_or_4(<<1,2,3>>, {true}),
819    ok = complex_or_4({1,2,3}, {true}),
820    error = complex_or_4({1,2,3,4}, {false}),
821
822    error = complex_or_4(<<1,2,3,4>>, []),
823    error = complex_or_4([], {true}),
824
825    %% complex_or_5/2
826    ok = complex_or_5(<<1>>, {false}),
827    ok = complex_or_5(<<1,2,3>>, {true}),
828    ok = complex_or_5(<<1,2,3,4>>, {false}),
829    ok = complex_or_5({1,2,3}, {false}),
830    ok = complex_or_5({1,2,3,4}, {false}),
831
832    error = complex_or_5(blurf, {false}),
833    error = complex_or_5(<<1>>, klarf),
834    error = complex_or_5(blurf, klarf),
835
836    %% complex_or_6/2
837    ok = complex_or_6({true,true}, {1,2,3,4}),
838    ok = complex_or_6({true,true}, <<1,2,3,4>>),
839    ok = complex_or_6({false,false}, <<1,2,3,4>>),
840    ok = complex_or_6({false,true}, <<1>>),
841    ok = complex_or_6({true,false}, {1}),
842    ok = complex_or_6({true,true}, {1}),
843
844    error = complex_or_6({false,false}, {1}),
845
846    error = complex_or_6({true}, {1,2,3,4}),
847    error = complex_or_6({}, {1,2,3,4}),
848    error = complex_or_6([], {1,2,3,4}),
849    error = complex_or_6([], {1,2,3,4}),
850    error = complex_or_6({true,false}, klurf),
851
852    ok.
853
854complex_or_1(A, B) ->
855    if
856	((3 < tuple_size(A)) and (tuple_size(A) < 9)) or
857	((2 < tuple_size(B)) and (tuple_size(B) < 7)) -> ok;
858	true -> error
859    end.
860
861complex_or_2(Tuple) ->
862    if
863	element(1, Tuple) or not (tuple_size(element(2, Tuple)) > 3) -> ok;
864	true -> error
865    end.
866
867complex_or_3(A, B) ->
868    if
869	not (size(B) > 3) or element(1, A) -> ok;
870	true -> error
871    end.
872
873complex_or_4(A, B) ->
874    if
875	not (is_tuple(A) and (size(A) > 3)) or element(1, B) -> ok;
876	true -> error
877    end.
878
879complex_or_5(A, B) ->
880    if
881	not (is_tuple(A) or (size(A) > 3)) or not element(1, B) -> ok;
882	true -> error
883    end.
884
885complex_or_6(A, B) ->
886    if
887	not (not element(1, A) and not element(2, A)) or
888	not (not (size(B) > 3)) -> ok;
889	true -> error
890    end.
891
892and_guard(Config) when is_list(Config) ->
893
894    %% 'and' combinations of literal true/false.
895
896    check(fun() -> if true and false -> ok; true -> error end end, error),
897    check(fun() -> if false and true -> ok; true -> error end end, error),
898    check(fun() -> if true and true -> ok end end, ok),
899    check(fun() -> if false and false -> ok; true -> error end end, error),
900
901    check(fun() -> if glurf and true -> ok; true -> error end end, error),
902    check(fun() -> if true and glurf -> ok; true -> error end end, error),
903    check(fun() -> if glurf and glurf -> ok; true -> error end end, error),
904
905    check(fun() ->
906		  {'EXIT',{if_clause,_}} =
907		      (catch if true and false -> ok;
908				false and true -> ok;
909				false and false -> ok
910			     end),
911		  exit
912	  end, exit),
913
914    %% 'and' combinations of true/false in variables.
915
916    True = id(true),
917    False = id(false),
918
919    check(fun() -> if True and False -> ok; true -> error end end, error),
920    check(fun() -> if False and True -> ok; true -> error end end, error),
921    check(fun() -> if True and True -> ok end end, ok),
922    check(fun() -> if False and False -> ok; true -> error end end, error),
923    check(fun() ->
924		  {'EXIT',{if_clause,_}} =
925		      (catch if True and False -> ok;
926				False and True -> ok;
927				False and False -> ok
928			     end),
929		  exit
930	  end, exit),
931
932    %% 'and' combinations of true/false and a non-boolean in variables.
933
934    Glurf = id(glurf),
935
936    check(fun() -> if True and Glurf -> ok; true -> error end end, error),
937    check(fun() -> if Glurf and True -> ok; true -> error end end, error),
938    check(fun() -> if True and True -> ok end end, ok),
939    check(fun() -> if Glurf and Glurf -> ok; true -> error end end, error),
940    check(fun() ->
941		  {'EXIT',{if_clause,_}} =
942		      (catch if True and Glurf -> ok;
943				Glurf and True -> ok;
944				Glurf and Glurf -> ok
945			     end),
946		  exit
947	  end, exit),
948
949    %% 'and' combinations of true/false with errors.
950    ATuple = id({a,b,c}),
951
952    check(fun() -> if True and element(42, ATuple) -> ok;
953		      true -> error end end, error),
954    check(fun() -> if element(42, ATuple) and True -> ok;
955		      true -> error end end, error),
956    check(fun() -> if True and True -> ok end end, ok),
957    check(fun() -> if element(42, ATuple) and element(42, ATuple) -> ok;
958		      true -> error end end, error),
959    check(fun() ->
960		  {'EXIT',{if_clause,_}} =
961		      (catch if True and element(42, ATuple) -> ok;
962				element(42, ATuple) and True -> ok;
963				element(42, ATuple) and element(42, ATuple) -> ok
964			     end),
965			exit
966		end, exit),
967
968    ok = relprod({'Set',a,b}, {'Set',a,b}),
969
970    ok = and_same_var(42),
971    {'EXIT',{if_clause,_}} = (catch and_same_var(x)),
972    ok.
973
974and_same_var(V) ->
975    B = is_integer(V),
976    if
977	B or B -> ok
978    end.
979
980relprod(R1, R2) when (erlang:size(R1) =:= 3) and (erlang:element(1,R1) =:= 'Set'), (erlang:size(R2) =:= 3) and (erlang:element(1,R2) =:= 'Set') ->
981    ok.
982
983
984xor_guard(Config) when is_list(Config) ->
985
986    %% 'xor' combinations of literal true/false.
987    check(fun() -> if true xor false -> ok end end, ok),
988    check(fun() -> if false xor true -> ok end end, ok),
989    check(fun() -> if true xor true -> ok; true -> error end end, error),
990    check(fun() -> if false xor false -> ok; true -> error end end, error),
991    check(fun() ->
992		  {'EXIT',{if_clause,_}} = (catch if false xor false -> ok end),
993		  exit
994	  end, exit),
995    check(fun() ->
996		  {'EXIT',{if_clause,_}} = (catch if true xor true -> ok end),
997		  exit
998	  end, exit),
999
1000
1001    %% 'xor' combinations using variables containing true/false.
1002
1003    True = id(true),
1004    False = id(false),
1005
1006    check(fun() -> if True xor False -> ok end end, ok),
1007    check(fun() -> if False xor True -> ok end end, ok),
1008    check(fun() -> if True xor True -> ok; true -> error end end, error),
1009    check(fun() -> if False xor False -> ok; true -> error end end, error),
1010    check(fun() ->
1011		  {'EXIT',{if_clause,_}} = (catch if False xor False -> ok end),
1012		  exit
1013	  end, exit),
1014    check(fun() ->
1015		  {'EXIT',{if_clause,_}} = (catch if True xor True -> ok end),
1016		  exit
1017	  end, exit),
1018
1019    ok.
1020
1021more_xor_guards(Config) when is_list(Config) ->
1022    True = id(true),
1023    False = id(false),
1024    ATuple = id({false,true,gurka}),
1025
1026    check(fun() ->
1027		  if element(42, ATuple) xor False -> ok;
1028		     true -> error end
1029	  end, error),
1030
1031    check(fun() ->
1032		  if False xor element(42, ATuple) xor False -> ok;
1033		     true -> error end
1034	  end, error),
1035
1036    check(fun() ->
1037		  if element(18, ATuple) xor element(42, ATuple) -> ok;
1038		     true -> error end
1039	  end, error),
1040
1041    check(fun() ->
1042		  if True xor element(42, ATuple) -> ok;
1043		     true -> error end
1044	  end, error),
1045
1046    check(fun() ->
1047		  if element(42, ATuple) xor True -> ok;
1048		     true -> error end
1049	  end, error),
1050    ok.
1051
1052build_in_guard(Config) when is_list(Config) ->
1053    SubBin = <<5.0/float>>,
1054    B = <<1,SubBin/binary,3.5/float>>,
1055    if
1056	B =:= <<1,SubBin/binary,3.5/float>> -> ok
1057    end.
1058
1059old_guard_tests(Config) when list(Config) ->
1060    %% Check that all the old guard tests are still recognized.
1061    list = og(Config),
1062    atom = og(an_atom),
1063    binary = og(<<1,2>>),
1064    float = og(3.14),
1065    integer = og(43),
1066    a_function = og(fun() -> ok end),
1067    pid = og(self()),
1068    reference = og(make_ref()),
1069    tuple = og({}),
1070
1071    number = on(45.333),
1072    number = on(-19),
1073    ok.
1074
1075og(V) when atom(V) -> atom;
1076og(V) when binary(V) -> binary;
1077og(V) when float(V) -> float;
1078og(V) when integer(V) -> integer;
1079og(V) when function(V) -> a_function;
1080og(V) when list(V) -> list;
1081og(V) when pid(V) -> pid;
1082og(V) when port(V) -> port;
1083og(V) when reference(V) -> reference;
1084og(V) when tuple(V) -> tuple;
1085og(_) -> what.
1086
1087on(V) when number(V) -> number;
1088on(_) -> not_number.
1089
1090complex_guard(_Config) ->
1091    _ = [true = do_complex_guard_1(X, Y, Z) ||
1092	    X <- [4,5], Y <- [4,5], Z <- [4,5]],
1093    _ = [true = do_complex_guard_1(X, Y, Z) ||
1094	    X <- [1,2,3], Y <- [1,2,3], Z <- [1,2,3]],
1095    _ = [catch do_complex_guard_1(X, Y, Z) ||
1096	    X <- [1,2,3,4,5], Y <- [0,6], Z <- [1,2,3,4,5]],
1097
1098    b = do_complex_guard_2(false, false, true),
1099    c = do_complex_guard_2(false, false, false),
1100    c = do_complex_guard_2(false, true,  true),
1101    a = do_complex_guard_2(false, true,  false),
1102
1103    c = do_complex_guard_2(true,  false, true),
1104    a = do_complex_guard_2(true,  false, false),
1105    c = do_complex_guard_2(true,  true,  true),
1106    a = do_complex_guard_2(true,  true,  false),
1107
1108    c = do_complex_guard_2(other, false, true),
1109    c = do_complex_guard_2(other, false, false),
1110    c = do_complex_guard_2(other, true,  true),
1111    c = do_complex_guard_2(other, true,  false),
1112
1113    c = do_complex_guard_2(false, other, true),
1114    c = do_complex_guard_2(false, other, false),
1115    c = do_complex_guard_2(true,  other, true),
1116    a = do_complex_guard_2(true,  other, false),
1117
1118    c = do_complex_guard_2(false, false, other),
1119    c = do_complex_guard_2(false, true,  other),
1120    c = do_complex_guard_2(true,  false, other),
1121    c = do_complex_guard_2(true,  true,  other),
1122
1123    c = do_complex_guard_2(false, other, other),
1124    c = do_complex_guard_2(true,  other, other),
1125    c = do_complex_guard_2(other, other, true),
1126    c = do_complex_guard_2(other, other, false),
1127    c = do_complex_guard_2(other, false, other),
1128    c = do_complex_guard_2(other, true,  other),
1129
1130    c = do_complex_guard_2(other, other, other),
1131
1132    ok.
1133
1134do_complex_guard_1(X1, Y1, Z1) ->
1135    if
1136	((X1 =:= 4) or (X1 =:= 5)) and
1137	((Y1 =:= 4) or (Y1 =:= 5)) and
1138	((Z1 =:= 4) or (Z1 =:= 5)) or
1139	((X1 =:= 1) or (X1 =:= 2) or (X1 =:= 3)) and
1140	((Y1 =:= 1) or (Y1 =:= 2) or (Y1 =:= 3)) and
1141	((Z1 =:= 1) or (Z1 =:= 2) or (Z1 =:= 3)) ->
1142	    true
1143    end.
1144
1145do_complex_guard_2(X, Y, Z) ->
1146  if
1147      (X orelse Y) andalso (not Z) -> a;
1148      Z andalso (not (X orelse Y)) -> b;
1149      true                         -> c
1150  end.
1151
1152gbif(Config) when is_list(Config) ->
1153    error = gbif_1(1, {false,true}),
1154    ok = gbif_1(2, {false,true}),
1155    ok.
1156
1157gbif_1(P, T) when element(P, T) -> ok;
1158gbif_1(_, _) -> error.
1159
1160
1161t_is_boolean(Config) when is_list(Config) ->
1162    true = is_boolean(true),
1163    true = is_boolean(false),
1164    true = is_boolean(id(true)),
1165    true = is_boolean(id(false)),
1166
1167    false = is_boolean(glurf),
1168    false = is_boolean(id(glurf)),
1169
1170    false = is_boolean([]),
1171    false = is_boolean(id([])),
1172    false = is_boolean(42),
1173    false = is_boolean(id(-42)),
1174
1175    false = is_boolean(math:pi()),
1176    false = is_boolean(384793478934378924978439789873478934897),
1177
1178    false = is_boolean(id(self())),
1179    false = is_boolean(id({x,y,z})),
1180    false = is_boolean(id([a,b,c])),
1181    false = is_boolean(id(make_ref())),
1182    false = is_boolean(id(<<1,2,3>>)),
1183    false = is_boolean({id(x),y,z}),
1184    false = is_boolean([id(a),b,c]),
1185
1186    ok = bool(true),
1187    ok = bool(false),
1188    ok = bool(id(true)),
1189    ok = bool(id(false)),
1190
1191    error = bool(glurf),
1192    error = bool(id(glurf)),
1193
1194    error = bool([]),
1195    error = bool(id([])),
1196    error = bool(42),
1197    error = bool(id(-42)),
1198
1199    error = bool(math:pi()),
1200    error = bool(384793478934378924978439789873478934897),
1201
1202    error = bool(id(self())),
1203    error = bool(id({x,y,z})),
1204    error = bool(id([a,b,c])),
1205    error = bool(id(make_ref())),
1206    error = bool(id(<<1,2,3>>)),
1207
1208    true = my_is_bool(true),
1209    true = my_is_bool(false),
1210    false = my_is_bool([]),
1211    false = my_is_bool([1,2,3,4]),
1212    false = my_is_bool({a,b,c}),
1213
1214    %% Cover code in beam_ssa_dead.
1215    ok = bool_semi(true),
1216    ok = bool_semi(false),
1217    error = bool_semi(a),
1218
1219    ok.
1220
1221bool(X) when is_boolean(X) -> ok;
1222bool(_) -> error.
1223
1224my_is_bool(V) ->
1225    Res = my_is_bool_a(V),
1226    Res = my_is_bool_b(V).
1227
1228my_is_bool_a(V) ->
1229    case V of
1230	true -> true;
1231	false -> true;
1232	_ -> false
1233    end.
1234
1235my_is_bool_b(V) ->
1236    case V of
1237	false -> true;
1238	true -> true;
1239	_ -> false
1240    end.
1241
1242bool_semi(V) when is_boolean(V); is_atom(not V) -> ok;
1243bool_semi(_) -> error.
1244
1245is_function_2(Config) when is_list(Config) ->
1246    true = is_function(id(fun ?MODULE:all/1), 1),
1247    true = is_function(id(fun() -> ok end), 0),
1248    false = is_function(id(fun ?MODULE:all/1), 0),
1249    false = is_function(id(fun() -> ok end), 1),
1250    {'EXIT',{badarg,_}} =
1251        (catch is_function(id(fun() -> ok end), -1) orelse error),
1252    {'EXIT',{badarg,_}} =
1253        (catch is_function(id(fun() -> ok end), '') orelse error),
1254
1255    F = fun(_) -> ok end,
1256    if
1257	is_function(F, 1) -> ok
1258    end.
1259
1260tricky(Config) when is_list(Config) ->
1261    not_ok = tricky_1(1, 2),
1262    not_ok = tricky_1(1, blurf),
1263    not_ok = tricky_1(foo, 2),
1264    not_ok = tricky_1(a, b),
1265
1266    error = tricky_2(0.5),
1267    error = tricky_2(a),
1268    error = tricky_2({a,b,c}),
1269
1270    false = rb(100000, [1], 42),
1271    true = rb(100000, [], 42),
1272    true = rb(555, [a,b,c], 19),
1273
1274    error = tricky_3(42),
1275    error = tricky_3(42.0),
1276    error = tricky_3(<<>>),
1277    error = tricky_3(#{}),
1278    error = tricky_3({a,b}),
1279
1280    {'EXIT',_} = (catch tricky_4(x)),
1281    {'EXIT',_} = (catch tricky_4(42)),
1282    {'EXIT',_} = (catch tricky_4(true)),
1283
1284    ok.
1285
1286tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok;
1287tricky_1(_, _) -> not_ok.
1288
1289tricky_2(X) when float(X) or float(X) -> ok;
1290tricky_2(_) -> error.
1291
1292tricky_3(X)
1293  when abs(X) or bit_size(X) or byte_size(X) or ceil(X) or
1294       float(X) or floor(X) or length(X) or
1295       map_size(X) or node() or node(X) or round(X) or
1296       self() or size(X) or tl(X) or trunc(X) or tuple_size(X) ->
1297    ok;
1298tricky_3(_) ->
1299    error.
1300
1301tricky_4(X) ->
1302    B = (abs(X) or abs(X)) =:= true,
1303    case B of
1304        true -> ok;
1305        false -> error
1306    end.
1307
1308%% From dets_v9:read_buckets/11, simplified.
1309
1310rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true;
1311rb(_, _, _) -> false.
1312
1313
1314-define(T(Op,A,B),
1315	ok = if A Op B -> ok; true -> error end,
1316	ok = if not (A Op B) -> error; true -> ok end,
1317	(fun(X, Y, True, False) ->
1318		 ok = if X Op Y -> ok; true -> error end,
1319		 ok = if False; X Op Y; False -> ok; true -> error end,
1320		 ok = if X Op Y, True -> ok; true -> error end,
1321		 ok = if not (X Op Y) -> error; true -> ok end,
1322		 ok = if False; not (X Op Y); False -> error; true -> ok end
1323	 end)(id(A), id(B), id(true), id(false))).
1324
1325-define(F(Op,A,B),
1326	ok = if A Op B -> error; true -> ok end,
1327	ok = if not (A Op B) -> ok; true -> error end,
1328	(fun(X, Y, True, False) ->
1329		 ok = if X Op Y -> error; true -> ok end,
1330		 ok = if False; X Op Y; False -> error; true -> ok end,
1331		 ok = if not (X Op Y); False -> ok; true -> error end,
1332		 ok = if not (X Op Y), True -> ok; true -> error end
1333	 end)(id(A), id(B), id(true), id(false))).
1334
1335
1336rel_ops(Config) when is_list(Config) ->
1337    ?T(=/=, 1, 1.0),
1338    ?F(=/=, 2, 2),
1339    ?F(=/=, {a}, {a}),
1340
1341    ?F(/=, a, a),
1342    ?F(/=, 0, 0.0),
1343    ?T(/=, 0, 1),
1344    ?F(/=, {a}, {a}),
1345
1346    ?T(==, 1, 1.0),
1347    ?F(==, a, {}),
1348
1349    ?F(=:=, 1, 1.0),
1350    ?T(=:=, 42.0, 42.0),
1351
1352    ?F(>, a, b),
1353    ?T(>, 42, 1.0),
1354    ?F(>, 42, 42.0),
1355
1356    ?T(<, a, b),
1357    ?F(<, 42, 1.0),
1358    ?F(<, 42, 42.0),
1359
1360    ?T(=<, 1.5, 5),
1361    ?F(=<, -9, -100.344),
1362    ?T(=<, 42, 42.0),
1363
1364    ?T(>=, 42, 42.0),
1365    ?F(>=, a, b),
1366    ?T(>=, 1.0, 0),
1367
1368    %% Coverage of beam_block:is_exact_eq_ok/1 and collect/1.
1369    true = any_atom /= id(42),
1370    true = [] /= id(42),
1371
1372    %% Coverage of beam_utils:bif_to_test/3
1373    Empty = id([]),
1374    ?T(==, [], Empty),
1375
1376    %% Cover beam_ssa_dead:turn_op('/=').
1377    ok = (fun(A, B) when is_atom(A) ->
1378                  X = id(A /= B),
1379                  if
1380                      X -> ok;
1381                      true -> error
1382                  end
1383          end)(a, b),
1384    ok = (fun(A, B) when is_atom(A) ->
1385                  X = id(B /= A),
1386                  if
1387                        X -> ok;
1388                        true -> error
1389                    end
1390            end)(a, b),
1391
1392    %% Cover beam_ssa_dead.
1393    Arrow = fun([T1,T2]) when T1 == $>, T2 == $>;
1394                              T1 == $<, T2 == $| ->  true;
1395               (_) -> false
1396            end,
1397    true = Arrow(">>"),
1398    true = Arrow("<|"),
1399    false = Arrow("><"),
1400    false = Arrow(""),
1401
1402    ok.
1403
1404-undef(TestOp).
1405
1406rel_op_combinations(Config) when is_list(Config) ->
1407    Digits0 = lists:seq(16#0030, 16#0039) ++
1408	lists:seq(16#0660, 16#0669) ++
1409	lists:seq(16#06F0, 16#06F9),
1410    Digits = gb_sets:from_list(Digits0),
1411    rel_op_combinations_1(16#0700, Digits),
1412
1413    BrokenRange0 = lists:seq(3, 5) ++
1414	lists:seq(10, 12) ++ lists:seq(14, 20),
1415    BrokenRange = gb_sets:from_list(BrokenRange0),
1416    rel_op_combinations_2(30, BrokenRange),
1417
1418    Red0 = [{I,2*I} || I <- lists:seq(0, 50)] ++
1419	[{I,5*I} || I <- lists:seq(51, 80)],
1420    Red = gb_trees:from_orddict(Red0),
1421    rel_op_combinations_3(100, Red),
1422
1423    rel_op_combinations_4().
1424
1425rel_op_combinations_1(0, _) ->
1426    ok;
1427rel_op_combinations_1(N, Digits) ->
1428    Bool = gb_sets:is_member(N, Digits),
1429    Bool = is_digit_1(N),
1430    Bool = is_digit_2(N),
1431    Bool = is_digit_3(N),
1432    Bool = is_digit_4(N),
1433    Bool = is_digit_5(N),
1434    Bool = is_digit_6(N),
1435    Bool = is_digit_7(N),
1436    Bool = is_digit_8(N),
1437    Bool = is_digit_9(42, N),
1438    Bool = is_digit_10(N, 0),
1439    Bool = is_digit_11(N, 0),
1440    rel_op_combinations_1(N-1, Digits).
1441
1442is_digit_1(X) when 16#0660 =< X, X =< 16#0669 -> true;
1443is_digit_1(X) when 16#0030 =< X, X =< 16#0039 -> true;
1444is_digit_1(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1445is_digit_1(_) -> false.
1446
1447is_digit_2(X) when (16#0030-1) < X, X =< 16#0039 -> true;
1448is_digit_2(X) when (16#0660-1) < X, X =< 16#0669 -> true;
1449is_digit_2(X) when (16#06F0-1) < X, X =< 16#06F9 -> true;
1450is_digit_2(_) -> false.
1451
1452is_digit_3(X) when 16#0660 =< X, X < (16#0669+1) -> true;
1453is_digit_3(X) when 16#0030 =< X, X < (16#0039+1) -> true;
1454is_digit_3(X) when 16#06F0 =< X, X < (16#06F9+1) -> true;
1455is_digit_3(_) -> false.
1456
1457is_digit_4(X) when (16#0660-1) < X, X < (16#0669+1) -> true;
1458is_digit_4(X) when (16#0030-1) < X, X < (16#0039+1) -> true;
1459is_digit_4(X) when (16#06F0-1) < X, X < (16#06F9+1) -> true;
1460is_digit_4(_) -> false.
1461
1462is_digit_5(X) when X >= 16#0660, X =< 16#0669 -> true;
1463is_digit_5(X) when X >= 16#0030, X =< 16#0039 -> true;
1464is_digit_5(X) when X >= 16#06F0, X =< 16#06F9 -> true;
1465is_digit_5(_) -> false.
1466
1467is_digit_6(X) when X > (16#0660-1), X =< 16#0669 -> true;
1468is_digit_6(X) when X > (16#0030-1), X =< 16#0039 -> true;
1469is_digit_6(X) when X > (16#06F0-1), X =< 16#06F9 -> true;
1470is_digit_6(_) -> false.
1471
1472is_digit_7(X) when 16#0660 =< X, X =< 16#0669 -> true;
1473is_digit_7(X) when 16#0030 =< X, X =< 16#003A, X =/= 16#003A -> true;
1474is_digit_7(X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1475is_digit_7(_) -> false.
1476
1477is_digit_8(X) when X =< 16#0039, X > (16#0030-1) -> true;
1478is_digit_8(X) when X =< 16#06F9, X > (16#06F0-1) -> true;
1479is_digit_8(X) when X =< 16#0669, X > (16#0660-1) -> true;
1480is_digit_8(16#0670) -> false;
1481is_digit_8(_) -> false.
1482
1483is_digit_9(A, 0) when A =:= 42 -> false;
1484is_digit_9(_, X) when X > 16#065F, X < 16#066A -> true;
1485is_digit_9(_, X) when 16#0030 =< X, X =< 16#0039 -> true;
1486is_digit_9(_, X) when 16#06F0 =< X, X =< 16#06F9 -> true;
1487is_digit_9(_, _) -> false.
1488
1489is_digit_10(0, 0) -> false;
1490is_digit_10(X, _) when X < 16#066A, 16#0660 =< X -> true;
1491is_digit_10(X, _) when 16#0030 =< X, X =< 16#0039 -> true;
1492is_digit_10(X, _) when 16#06F0 =< X, X =< 16#06F9 -> true;
1493is_digit_10(_, _) -> false.
1494
1495is_digit_11(0, 0) -> false;
1496is_digit_11(X, _) when X =< 16#0669, 16#0660 =< X -> true;
1497is_digit_11(X, _) when 16#0030 =< X, X =< 16#0039 -> true;
1498is_digit_11(X, _) when 16#06F0 =< X, X =< 16#06F9 -> true;
1499is_digit_11(_, _) -> false.
1500
1501rel_op_combinations_2(0, _) ->
1502    ok;
1503rel_op_combinations_2(N, Range) ->
1504    Bool = gb_sets:is_member(N, Range),
1505    Bool = broken_range_1(N),
1506    Bool = broken_range_2(N),
1507    Bool = broken_range_3(N),
1508    Bool = broken_range_4(N),
1509    Bool = broken_range_5(N),
1510    Bool = broken_range_6(N),
1511    Bool = broken_range_7(N),
1512    Bool = broken_range_8(N),
1513    Bool = broken_range_9(N),
1514    Bool = broken_range_10(N),
1515    Bool = broken_range_11(N),
1516    Bool = broken_range_12(N),
1517    Bool = broken_range_13(N),
1518    rel_op_combinations_2(N-1, Range).
1519
1520broken_range_1(X) when X >= 10, X =< 20, X =/= 13 -> true;
1521broken_range_1(X) when X >= 3, X =< 5 -> true;
1522broken_range_1(_) -> false.
1523
1524broken_range_2(X) when X >= 10, X =< 12 -> true;
1525broken_range_2(X) when X >= 14, X =< 20 -> true;
1526broken_range_2(X) when X >= 3, X =< 5 -> true;
1527broken_range_2(_) -> false.
1528
1529broken_range_3(X) when X >= 10, X =< 12 -> true;
1530broken_range_3(X) when X >= 14, X < 21 -> true;
1531broken_range_3(3) -> true;
1532broken_range_3(4) -> true;
1533broken_range_3(5) -> true;
1534broken_range_3(_) -> false.
1535
1536broken_range_4(X) when X =< 5, X >= 3 -> true;
1537broken_range_4(X) when X >= 10, X =< 20, X =/= 13 -> true;
1538broken_range_4(X) when X =< 100 -> false;
1539broken_range_4(_) -> false.
1540
1541broken_range_5(X) when X >= 10, X =< 20, X =/= 13 -> true;
1542broken_range_5(X) when X > 2, X =< 5 -> true;
1543broken_range_5(_) -> false.
1544
1545broken_range_6(X) when X >= 10, X =< 20, X =/= 13 -> true;
1546broken_range_6(X) when X > 2, X < 6 -> true;
1547broken_range_6(_) -> false.
1548
1549broken_range_7(X) when X > 2, X < 6 -> true;
1550broken_range_7(X) when X >= 10, X =< 20, X =/= 13 -> true;
1551broken_range_7(X) when X > 30 -> false;
1552broken_range_7(_) -> false.
1553
1554broken_range_8(X) when X >= 10, X =< 20, X =/= 13 -> true;
1555broken_range_8(X) when X =:= 3 -> true;
1556broken_range_8(X) when X >= 3, X =< 5 -> true;
1557broken_range_8(_) -> false.
1558
1559broken_range_9(X) when X >= 10, X =< 20, X =/= 13 -> true;
1560broken_range_9(X) when X =:= 13 -> false;
1561broken_range_9(X) when X >= 3, X =< 5 -> true;
1562broken_range_9(_) -> false.
1563
1564broken_range_10(X) when X >= 3, X =< 5 -> true;
1565broken_range_10(X) when X >= 10, X =< 20, X =/= 13 -> true;
1566broken_range_10(X) when X =/= 13 -> false;
1567broken_range_10(_) -> false.
1568
1569broken_range_11(X) when X >= 10, X =< 20, X =/= 13 -> true;
1570broken_range_11(X) when is_tuple(X), X =:= 10 -> true;
1571broken_range_11(X) when X >= 3, X =< 5 -> true;
1572broken_range_11(_) -> false.
1573
1574broken_range_12(X) when X >= 3, X =< 5 -> true;
1575broken_range_12(X) when X >= 10, X =< 20, X =/= 13 -> true;
1576broken_range_12(X) when X < 30, X > 20 -> false;
1577broken_range_12(_) -> false.
1578
1579broken_range_13(X) when X >= 10, X =< 20, 13 =/= X -> true;
1580broken_range_13(X) when X >= 3, X =< 5 -> true;
1581broken_range_13(_) -> false.
1582
1583rel_op_combinations_3(0, _) ->
1584    ok;
1585rel_op_combinations_3(N, Red) ->
1586    Val = case gb_trees:lookup(N, Red) of
1587	      none -> none;
1588	      {value,V} -> V
1589	  end,
1590    Val = redundant_1(N),
1591    Val = redundant_2(N),
1592    Val = redundant_3(N),
1593    Val = redundant_4(N),
1594    Val = redundant_5(N),
1595    Val = redundant_6(N),
1596    Val = redundant_7(N),
1597    Val = redundant_8(N),
1598    Val = redundant_9(N),
1599    Val = redundant_10(N),
1600    Val = redundant_11(N),
1601    Val = redundant_12(N),
1602    rel_op_combinations_3(N-1, Red).
1603
1604redundant_1(X) when X >= 51, X =< 80 -> 5*X;
1605redundant_1(X) when X < 51 -> 2*X;
1606redundant_1(_) -> none.
1607
1608redundant_2(X) when X < 51 -> 2*X;
1609redundant_2(X) when X >= 51, X =< 80 -> 5*X;
1610redundant_2(_) -> none.
1611
1612redundant_3(X) when X < 51 -> 2*X;
1613redundant_3(X) when X =< 80, X >= 51 -> 5*X;
1614redundant_3(X) when X =/= 100 -> none;
1615redundant_3(_) -> none.
1616
1617redundant_4(X) when X < 51 -> 2*X;
1618redundant_4(X) when X =< 80, X > 50 -> 5*X;
1619redundant_4(X) when X =/= 100 -> none;
1620redundant_4(_) -> none.
1621
1622redundant_5(X) when X < 51 -> 2*X;
1623redundant_5(X) when X > 50, X < 81 -> 5*X;
1624redundant_5(X) when X =< 10 -> none;
1625redundant_5(_) -> none.
1626
1627redundant_6(X) when X > 50, X =< 80 -> 5*X;
1628redundant_6(X) when X < 51 -> 2*X;
1629redundant_6(_) -> none.
1630
1631redundant_7(X) when is_integer(X), X >= 51, X =< 80 -> 5*X;
1632redundant_7(X) when is_integer(X), X < 51 -> 2*X;
1633redundant_7(_) -> none.
1634
1635redundant_8(X) when X >= 51, X =< 80 -> 5*X;
1636redundant_8(X) when X < 51 -> 2*X;
1637redundant_8(_) -> none.
1638
1639redundant_9(X) when X >= 51, X =< 80 -> 5*X;
1640redundant_9(X) when X < 51 -> 2*X;
1641redundant_9(90) -> none;
1642redundant_9(X) when X =/= 90 -> none;
1643redundant_9(_) -> none.
1644
1645redundant_10(X) when X >= 51, X =< 80 -> 5*X;
1646redundant_10(X) when X < 51 -> 2*X;
1647redundant_10(90) -> none;
1648redundant_10(X) when X =:= 90 -> none;
1649redundant_10(_) -> none.
1650
1651redundant_11(X) when X < 51 -> 2*X;
1652redundant_11(X) when X =:= 10 -> 2*X;
1653redundant_11(X) when X >= 51, X =< 80 -> 5*X;
1654redundant_11(_) -> none.
1655
1656redundant_12(50) -> 100;
1657redundant_12(X) when X >= 50, X =< 80 -> 5*X;
1658redundant_12(X) when X < 51 -> 2*X;
1659redundant_12(_) -> none.
1660
1661rel_op_combinations_4() ->
1662    ne = rel_op_vars_1(id(a), id(b)),
1663    le = rel_op_vars_1(id(x), id(x)),
1664
1665    ne = rel_op_vars_2(id(a), id(b)),
1666    ge = rel_op_vars_2(id(x), id(x)),
1667
1668    ok.
1669
1670rel_op_vars_1(X, N) when X =/= N -> ne;
1671rel_op_vars_1(X, N) when X =< N -> le.
1672
1673rel_op_vars_2(X, N) when X =/= N -> ne;
1674rel_op_vars_2(X, N) when X >= N -> ge.
1675
1676%% Exhaustively test all combinations of relational operators
1677%% to ensure the correctness of the optimizations in beam_ssa_dead.
1678
1679generated_combinations(_Config) ->
1680    Mod = ?FUNCTION_NAME,
1681    RelOps = ['=:=','=/=','==','/=','<','=<','>=','>'],
1682    Combinations0 = [{Op1,Op2} || Op1 <- RelOps, Op2 <- RelOps],
1683    Combinations1 = gen_lit_combs(Combinations0),
1684    Combinations2 = [{neq,Comb} ||
1685                        {_Op1,_Lit1,Op2,_Lit2}=Comb <- Combinations1,
1686                        Op2 =:= '=/=' orelse Op2 =:= '/='] ++ Combinations1,
1687    Combinations = gen_func_names(Combinations2, 0),
1688    Fs = gen_rel_op_functions(Combinations),
1689    Tree = ?Q(["-module('@Mod@').",
1690               "-compile([export_all,nowarn_export_all])."]) ++ Fs,
1691    %%merl:print(Tree),
1692    Opts = test_lib:opt_opts(?MODULE),
1693    {ok,_Bin} = merl:compile_and_load(Tree, Opts),
1694    test_combinations(Combinations, Mod).
1695
1696gen_lit_combs([{Op1,Op2}|T]) ->
1697    [{Op1,7,Op2,6},
1698     {Op1,7.0,Op2,6},
1699     {Op1,7,Op2,6.0},
1700     {Op1,7.0,Op2,6.0},
1701
1702     {Op1,7,Op2,7},
1703     {Op1,7.0,Op2,7},
1704     {Op1,7,Op2,7.0},
1705     {Op1,7.0,Op2,7.0},
1706
1707     {Op1,6,Op2,7},
1708     {Op1,6.0,Op2,7},
1709     {Op1,6,Op2,7.0},
1710     {Op1,6.0,Op2,7.0}|gen_lit_combs(T)];
1711gen_lit_combs([]) -> [].
1712
1713gen_func_names([E|Es], I) ->
1714    Name = list_to_atom("f" ++ integer_to_list(I)),
1715    [{Name,E}|gen_func_names(Es, I+1)];
1716gen_func_names([], _) -> [].
1717
1718gen_rel_op_functions([{Name,{neq,{Op1,Lit1,Op2,Lit2}}}|T]) ->
1719    %% Note that in the translation to SSA, '=/=' will be
1720    %% translated to '=:=' in a guard (with switched success
1721    %% and failure labels). Therefore, to test the optimization,
1722    %% we must use '=/=' (or '/=') in a body context.
1723    %%
1724    %% Here is an example of a generated function:
1725    %%
1726    %%     f160(A) when erlang:'>='(A, 7) ->
1727    %%          one;
1728    %%     f160(A) ->
1729    %%          true = erlang:'/='(A, 7),
1730    %%          two.
1731    [?Q("'@Name@'(A) when erlang:'@Op1@'(A, _@Lit1@) -> one;
1732        '@Name@'(A) -> true = erlang:'@Op2@'(A, _@Lit2@), two. ")|
1733     gen_rel_op_functions(T)];
1734gen_rel_op_functions([{Name,{Op1,Lit1,Op2,Lit2}}|T]) ->
1735    %% Example of a generated function:
1736    %%
1737    %% f721(A) when erlang:'=<'(A, 7.0) -> one;
1738    %% f721(A) when erlang:'<'(A, 6) -> two;
1739    %% f721(_) -> three.
1740    [?Q("'@Name@'(A) when erlang:'@Op1@'(A, _@Lit1@) -> one;
1741        '@Name@'(A) when erlang:'@Op2@'(A, _@Lit2@) -> two;
1742        '@Name@'(_) -> three.")|gen_rel_op_functions(T)];
1743gen_rel_op_functions([]) -> [].
1744
1745test_combinations([{Name,E}|T], Mod) ->
1746    try
1747        test_combinations_1([5,6,7,8,9], E, fun Mod:Name/1),
1748        test_combination(6.5, E, fun Mod:Name/1)
1749    catch
1750        error:Reason:Stk ->
1751            io:format("~p: ~p\n", [Name,E]),
1752            erlang:raise(error, Reason, Stk)
1753    end,
1754    test_combinations(T, Mod);
1755test_combinations([], _Mod) -> ok.
1756
1757test_combinations_1([V|Vs], E, Fun) ->
1758    test_combination(V, E, Fun),
1759    test_combination(float(V), E, Fun),
1760    test_combinations_1(Vs, E, Fun);
1761test_combinations_1([], _, _) -> ok.
1762
1763test_combination(Val, {neq,Expr}, Fun) ->
1764    Result = eval_combination_expr(Expr, Val),
1765    Result = try
1766                 Fun(Val)                       %Returns 'one' or 'two'.
1767             catch
1768                 error:{badmatch,_} ->
1769                     three
1770             end;
1771test_combination(Val, Expr, Fun) ->
1772    Result = eval_combination_expr(Expr, Val),
1773    Result = Fun(Val).
1774
1775eval_combination_expr({Op1,Lit1,Op2,Lit2}, Val) ->
1776    case erlang:Op1(Val, Lit1) of
1777        true ->
1778            one;
1779        false ->
1780            case erlang:Op2(Val, Lit2) of
1781                true -> two;
1782                false -> three
1783            end
1784    end.
1785
1786%% Test type tests on literal values. (From emulator test suites.)
1787literal_type_tests(Config) when is_list(Config) ->
1788    %% Generate an Erlang module with all different type of type tests.
1789    Tests = make_test([{T,L} || T <- type_tests(), L <- literals()] ++
1790			    [{is_function,L1,L2} ||
1791				L1 <- literals(), L2 <- literals()]),
1792    Mod = literal_test,
1793    Anno = erl_anno:new(0),
1794    Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
1795    Form = [{attribute,Anno,module,Mod},
1796            {attribute,Anno,compile,export_all},
1797            Func, {eof,999}],
1798
1799    %% Print generated code for inspection.
1800    lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
1801
1802    %% Test compile:form/1.  This implies full optimization (default).
1803    {ok,Mod,Code1} = compile:forms(Form),
1804    smoke_disasm(Config, Mod, Code1),
1805    {module,Mod} = code:load_binary(Mod, Mod, Code1),
1806    Mod:test(),
1807    true = code:delete(Mod),
1808    code:purge(Mod),
1809
1810    %% Test compile:form/2.  Turn off all optimizations.
1811    {ok,Mod,Code2} = compile:forms(Form, [binary,report,time,
1812						no_copt,no_postopt]),
1813    smoke_disasm(Config, Mod, Code2),
1814    {module,Mod} = code:load_binary(Mod, Mod, Code2),
1815    Mod:test(),
1816    true = code:delete(Mod),
1817    code:purge(Mod),
1818    ok.
1819
1820make_test([{T,L1,L2}|Ts]) ->
1821    [test(T, L1, L2)|make_test(Ts)];
1822make_test([{T,L}|Ts]) ->
1823    [test(T, L)|make_test(Ts)];
1824make_test([]) -> [].
1825
1826test(T, L) ->
1827    S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T,L,T,L]),
1828    S = lists:flatten(S0),
1829    {ok,Toks,_Line} = erl_scan:string(S),
1830    {ok,E} = erl_parse:parse_exprs(Toks),
1831    {value,Val,_Bs} = erl_eval:exprs(E, []),
1832    Anno = erl_anno:new(0),
1833    {match,Anno,{atom,Anno,Val},hd(E)}.
1834
1835test(T, L1, L2) ->
1836    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]),
1837    S = lists:flatten(S0),
1838    {ok,Toks,_Line} = erl_scan:string(S),
1839    {ok,E} = erl_parse:parse_exprs(Toks),
1840    {value,Val,_Bs} = erl_eval:exprs(E, []),
1841    Anno = erl_anno:new(0),
1842    {match,Anno,{atom,Anno,Val},hd(E)}.
1843
1844smoke_disasm(Config, Mod, Bin) ->
1845    Priv = proplists:get_value(priv_dir, Config),
1846    File = filename:join(Priv, atom_to_list(Mod)++".beam"),
1847    ok = file:write_file(File, Bin),
1848    test_lib:smoke_disasm(File).
1849
1850literals() ->
1851    [42,
1852     3.14,
1853     -3,
1854     32982724987789283473473838474,
1855     [],
1856     xxxx,
1857     {a,b,c},
1858     [a,list],
1859     <<1,2,3>>,
1860     <<42:17>>].
1861
1862type_tests() ->
1863    [is_boolean,
1864     is_integer,
1865     is_float,
1866     is_number,
1867     is_atom,
1868     is_list,
1869     is_tuple,
1870     is_pid,
1871     is_reference,
1872     is_port,
1873     is_binary,
1874     is_bitstring,
1875     is_function,
1876     is_map].
1877
1878basic_andalso_orelse(Config) when is_list(Config) ->
1879    T = id({type,integers,23,42}),
1880    65 = if
1881	     ((element(1, T) =:= type) andalso (tuple_size(T) =:= 4) andalso
1882	      element(2, T)) == integers ->
1883		 element(3, T) + element(4, T);
1884	     true -> error
1885	 end,
1886    65 = case [] of
1887	     [] when ((element(1, T) =:= type) andalso (tuple_size(T) =:= 4) andalso
1888		      element(2, T)) == integers ->
1889		 element(3, T) + element(4, T)
1890	 end,
1891
1892    42 = basic_rt({type,integers,40,2}),
1893    5.0 = basic_rt({vector,{3.0,4.0}}),
1894    20 = basic_rt(['+',3,7]),
1895    {'Set',a,b} = basic_rt({{'Set',a,b},{'Set',a,b}}),
1896    12 = basic_rt({klurf,4}),
1897
1898    error = basic_rt({type,integers,40,2,3}),
1899    error = basic_rt({kalle,integers,40,2}),
1900    error = basic_rt({kalle,integers,40,2}),
1901    error = basic_rt({1,2}),
1902    error = basic_rt([]),
1903
1904    RelProdBody =
1905	fun(R1, R2) ->
1906		if
1907		    (erlang:size(R1) =:= 3) andalso (erlang:element(1,R1) =:= 'Set'),
1908		    (erlang:size(R2) =:= 3) andalso (erlang:element(1,R2) =:= 'Set') ->
1909			ok
1910		end
1911	end,
1912
1913    ok = RelProdBody({'Set',a,b}, {'Set',a,b}),
1914
1915    %% 'andalso'/'orelse' with calls known to fail already at compile time.
1916    %% Used to crash the code generator.
1917    error = (fun() ->
1918		     R = {vars,true},
1919		     if
1920			 is_record(R, vars, 2) andalso element(99, R) -> ok;
1921			 true -> error
1922		     end
1923	     end)(),
1924    error = (fun(X) ->
1925		     L = {a,b,c},
1926		     if
1927			 is_list(X) andalso length(L) > 4 -> ok;
1928			 true -> error
1929		     end
1930	     end)([]),
1931    ok.
1932
1933basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 4 andalso element(1, T) =:= type andalso
1934		 element(2, T) == integers ->
1935    element(3, T) + element(4, T);
1936basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 2 andalso element(1, T) =:= vector ->
1937    {X,Y} = element(2, T),
1938    if
1939	is_float(X), is_float(Y) ->
1940	    math:sqrt(X*X+Y*Y)
1941    end;
1942basic_rt(['+',A,B]) ->
1943    2*id(A+B);
1944basic_rt({R1,R2}) when erlang:size(R1) =:= 3 andalso erlang:element(1,R1) =:= 'Set',
1945		       erlang:size(R2) =:= 3 andalso erlang:element(1,R2) =:= 'Set' ->
1946    R1 = id(R1),
1947    R2 = id(R2),
1948    R1;
1949basic_rt(T) when is_tuple(T) andalso tuple_size(T) =:= 2 andalso element(1, T) =:= klurf ->
1950    3*id(element(2, T));
1951basic_rt(_) ->
1952    error.
1953
1954traverse_dcd(Config) when is_list(Config) ->
1955    L0 = [{log_header,dcd_log,"1.0",a,b,c},{log_header,dcd_log,"2.0",a,b,c},
1956	  {log_header,dcd_log,"0.0",a,b,c},blurf],
1957    {cont,[{log_header,dcd_log,"0.0",a,b,c},blurf],log,funny} =
1958	traverse_dcd({cont,L0}, log, funny),
1959    L1 = [{log_header,dcd_log,"1.0"}],
1960    {cont,L1,log,funny} = traverse_dcd({cont,L1}, log, funny),
1961    L2 = [{a,tuple}],
1962    {cont,L2,log,funny} = traverse_dcd({cont,L2}, log, funny),
1963    ok.
1964
1965%% The function starts out with 3 arguments in {x,0}, {x,1}, {x,2}.
1966%% The outer match of a two tuple will places the first element in {x,3} and
1967%% second in {x,4}. The guard for the first clause must make ensure that all of those
1968%% registers are restored before entering the second clause.
1969%%
1970%% (From mnesia_checkpoint.erl, modified.)
1971
1972traverse_dcd({Cont,[LogH|Rest]},Log,Fun)
1973  when is_tuple(LogH) andalso tuple_size(LogH) =:= 6 andalso element(1, LogH) =:= log_header
1974andalso erlang:element(2,LogH) == dcd_log,
1975is_tuple(LogH) andalso tuple_size(LogH) =:= 6 andalso element(1, LogH) =:= log_header
1976andalso erlang:element(3,LogH) >= "1.0" ->
1977    traverse_dcd({Cont,Rest},Log,Fun);
1978traverse_dcd({Cont,Recs},Log,Fun) ->
1979    {Cont,Recs,Log,Fun}.
1980
1981
1982check_qlc_hrl(Config) when is_list(Config) ->
1983    St = {r1,false,dum},
1984    foo = cqlc(qlc, q, [{lc,1,2,3}], St),
1985    foo = cqlc(qlc, q, [{lc,1,2,3},b], St),
1986    St = cqlc(qlc, q, [], St),
1987    St = cqlc(qlc, blurf, [{lc,1,2,3},b], St),
1988    St = cqlc(q, q, [{lc,1,2,3},b], St),
1989    St = cqlc(qlc, q, [{lc,1,2,3},b,c], St),
1990    St = cqlc(qlc, q, [a,b], St),
1991    {r1,true,kalle} = cqlc(qlc, q, [{lc,1,2,3},b], {r1,true,kalle}),
1992    ok.
1993
1994%% From erl_lint.erl; original name was check_qlc_hrl/4.
1995cqlc(M, F, As, St) ->
1996    Arity = length(As),
1997    case As of
1998        [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q,
1999                                Arity < 3,
2000                                not (((element(1, St) =:= r1) orelse fail) and (tuple_size(St) =:= 3) and element(2, St)) ->
2001            foo;
2002        _ ->
2003            St
2004    end.
2005
2006%% OTP-7679: Thanks to Hunter Morris.
2007andalso_semi(Config) when is_list(Config) ->
2008    ok = andalso_semi_foo(0),
2009    ok = andalso_semi_foo(1),
2010    fc(catch andalso_semi_foo(2)),
2011
2012    ok = andalso_semi_bar([a,b,c]),
2013    ok = andalso_semi_bar(1),
2014    fc(catch andalso_semi_bar([a,b])),
2015
2016    ok = andalso_semi_dispatch(name, fun andalso_semi/1),
2017    ok = andalso_semi_dispatch(name, fun ?MODULE:andalso_semi/1),
2018    ok = andalso_semi_dispatch(name, {?MODULE,andalso_semi,1}),
2019    fc(catch andalso_semi_dispatch(42, fun andalso_semi/1)),
2020    fc(catch andalso_semi_dispatch(name, not_fun)),
2021    fc(catch andalso_semi_dispatch(name, fun andalso_semi_dispatch/2)),
2022    fc(catch andalso_semi_dispatch(42, {a,b})),
2023
2024    ok.
2025
2026andalso_semi_foo(Bar) when is_integer(Bar) andalso Bar =:= 0; Bar =:= 1 ->
2027   ok.
2028
2029andalso_semi_bar(Bar) when is_list(Bar) andalso length(Bar) =:= 3; Bar =:= 1 ->
2030   ok.
2031
2032andalso_semi_dispatch(Registry, MFAOrFun) when
2033      is_atom(Registry) andalso is_function(MFAOrFun, 1);
2034      is_atom(Registry) andalso tuple_size(MFAOrFun) == 3 ->
2035    ok.
2036
2037t_tuple_size(Config) when is_list(Config) ->
2038    10 = do_tuple_size({1,2,3,4}),
2039    fc(catch do_tuple_size({1,2,3})),
2040    fc(catch do_tuple_size(42)),
2041
2042    error = ludicrous_tuple_size({a,b,c}),
2043    error = ludicrous_tuple_size([a,b,c]),
2044
2045    good_ip({1,2,3,4}),
2046    good_ip({1,2,3,4,5,6,7,8}),
2047    error = validate_ip({42,11}),
2048    error = validate_ip(atom),
2049
2050    ok.
2051
2052do_tuple_size(T) when tuple_size(T) =:= 4 ->
2053    {A,B,C,D} = T,
2054    A+B+C+D.
2055
2056ludicrous_tuple_size(T)
2057  when tuple_size(T) =:= 16#7777777777777777777777777777777777 -> ok;
2058ludicrous_tuple_size(T)
2059  when tuple_size(T) =:= 16#10000000000000000 -> ok;
2060ludicrous_tuple_size(T)
2061  when tuple_size(T) =:= (1 bsl 64) - 1 -> ok;
2062ludicrous_tuple_size(T)
2063  when tuple_size(T) =:= 16#FFFFFFFFFFFFFFFF -> ok;
2064ludicrous_tuple_size(_) -> error.
2065
2066good_ip(IP) ->
2067    IP = validate_ip(IP).
2068
2069validate_ip(Value) when is_tuple(Value) andalso
2070                        ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
2071    %% size/1 (converted to tuple_size) used more than once.
2072    Value;
2073validate_ip(_) ->
2074    error.
2075
2076%%
2077%% The binary_part/2,3 guard BIFs
2078%%
2079-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))).
2080mask_error({'EXIT',{Err,_}}) ->
2081    Err;
2082mask_error(Else) ->
2083    Else.
2084
2085%% Test the binary_part/2,3 guard (GC) BIFs.
2086binary_part(Config) when is_list(Config) ->
2087    %% This is more or less a copy of what the guard_SUITE in emulator
2088    %% does to cover the guard bif's
2089    1 = bptest(<<1,2,3>>),
2090    2 = bptest(<<2,1,3>>),
2091    error = bptest(<<1>>),
2092    error = bptest(<<>>),
2093    error = bptest(apa),
2094    3 = bptest(<<2,3,3>>),
2095    % With one variable (pos)
2096    1 = bptest(<<1,2,3>>,1),
2097    2 = bptest(<<2,1,3>>,1),
2098    error = bptest(<<1>>,1),
2099    error = bptest(<<>>,1),
2100    error = bptest(apa,1),
2101    3 = bptest(<<2,3,3>>,1),
2102    % With one variable (length)
2103    1 = bptesty(<<1,2,3>>,1),
2104    2 = bptesty(<<2,1,3>>,1),
2105    error = bptesty(<<1>>,1),
2106    error = bptesty(<<>>,1),
2107    error = bptesty(apa,1),
2108    3 = bptesty(<<2,3,3>>,2),
2109    % With one variable (whole tuple)
2110    1 = bptestx(<<1,2,3>>,{1,1}),
2111    2 = bptestx(<<2,1,3>>,{1,1}),
2112    error = bptestx(<<1>>,{1,1}),
2113    error = bptestx(<<>>,{1,1}),
2114    error = bptestx(apa,{1,1}),
2115    3 = bptestx(<<2,3,3>>,{1,2}),
2116    % With two variables
2117    1 = bptest(<<1,2,3>>,1,1),
2118    2 = bptest(<<2,1,3>>,1,1),
2119    error = bptest(<<1>>,1,1),
2120    error = bptest(<<>>,1,1),
2121    error = bptest(apa,1,1),
2122    3 = bptest(<<2,3,3>>,1,2),
2123    % Direct (autoimported) call, these will be evaluated by the compiler...
2124    <<2>> = binary_part(<<1,2,3>>,1,1),
2125    <<1>> = binary_part(<<2,1,3>>,1,1),
2126    % Compiler warnings due to constant evaluation expected (3)
2127    badarg = ?MASK_ERROR(binary_part(<<1>>,1,1)),
2128    badarg = ?MASK_ERROR(binary_part(<<>>,1,1)),
2129    badarg = ?MASK_ERROR(binary_part(apa,1,1)),
2130    <<3,3>> = binary_part(<<2,3,3>>,1,2),
2131    % Direct call through apply
2132    <<2>> = apply(erlang,binary_part,[<<1,2,3>>,1,1]),
2133    <<1>> = apply(erlang,binary_part,[<<2,1,3>>,1,1]),
2134    % Compiler warnings due to constant evaluation expected (3)
2135    badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<1>>,1,1])),
2136    badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<>>,1,1])),
2137    badarg = ?MASK_ERROR(apply(erlang,binary_part,[apa,1,1])),
2138    <<3,3>> = apply(erlang,binary_part,[<<2,3,3>>,1,2]),
2139    % Constant propagation
2140     Bin = <<1,2,3>>,
2141     ok = if
2142		    binary_part(Bin,1,1) =:= <<2>> ->
2143			ok;
2144		    %% Compiler warning, clause cannot match (expected)
2145		    true ->
2146			error
2147		end,
2148     ok = if
2149		    binary_part(Bin,{1,1}) =:= <<2>> ->
2150			ok;
2151		    %% Compiler warning, clause cannot match (expected)
2152		    true ->
2153			error
2154		end,
2155    ok.
2156
2157
2158bptest(B) when length(B) =:= 1337 ->
2159    1;
2160bptest(B) when binary_part(B,{1,1}) =:= <<2>> ->
2161    1;
2162bptest(B) when erlang:binary_part(B,1,1) =:= <<1>> ->
2163    2;
2164bptest(B)  when erlang:binary_part(B,{1,2}) =:= <<3,3>> ->
2165    3;
2166bptest(_) ->
2167    error.
2168
2169bptest(B,A) when length(B) =:= A ->
2170    1;
2171bptest(B,A) when binary_part(B,{A,1}) =:= <<2>> ->
2172    1;
2173bptest(B,A) when erlang:binary_part(B,A,1) =:= <<1>> ->
2174    2;
2175bptest(B,A)  when erlang:binary_part(B,{A,2}) =:= <<3,3>> ->
2176    3;
2177bptest(_,_) ->
2178    error.
2179
2180bptestx(B,A) when length(B) =:= A ->
2181    1;
2182bptestx(B,A) when binary_part(B,A) =:= <<2>> ->
2183    1;
2184bptestx(B,A) when erlang:binary_part(B,A) =:= <<1>> ->
2185    2;
2186bptestx(B,A)  when erlang:binary_part(B,A) =:= <<3,3>> ->
2187    3;
2188bptestx(_,_) ->
2189    error.
2190
2191bptesty(B,A) when length(B) =:= A ->
2192    1;
2193bptesty(B,A) when binary_part(B,{1,A}) =:= <<2>> ->
2194    1;
2195bptesty(B,A) when erlang:binary_part(B,1,A) =:= <<1>> ->
2196    2;
2197bptesty(B,A)  when erlang:binary_part(B,{1,A}) =:= <<3,3>> ->
2198    3;
2199bptesty(_,_) ->
2200    error.
2201
2202bptest(B,A,_C) when length(B) =:= A ->
2203    1;
2204bptest(B,A,C) when binary_part(B,{A,C}) =:= <<2>> ->
2205    1;
2206bptest(B,A,C) when erlang:binary_part(B,A,C) =:= <<1>> ->
2207    2;
2208bptest(B,A,C)  when erlang:binary_part(B,{A,C}) =:= <<3,3>> ->
2209    3;
2210bptest(_,_,_) ->
2211    error.
2212
2213-define(FAILING(C),
2214	if
2215	    C -> ct:fail(should_fail);
2216	    true -> ok
2217	end,
2218	if
2219	    true, C -> ct:fail(should_fail);
2220	    true -> ok
2221	end).
2222
2223bad_constants(Config) when is_list(Config) ->
2224    ?FAILING(false),
2225    ?FAILING([]),
2226    ?FAILING([a]),
2227    ?FAILING([Config]),
2228    ?FAILING({a,b}),
2229    ?FAILING({a,Config}),
2230    ?FAILING(<<1>>),
2231    ?FAILING(42),
2232    ?FAILING(3.14),
2233    ok.
2234
2235bad_guards(Config) when is_list(Config) ->
2236    if erlang:float(self()); true -> ok end,
2237
2238    fc(catch bad_guards_1(1, [])),
2239    fc(catch bad_guards_1(1, [2])),
2240    fc(catch bad_guards_1(atom, [2])),
2241
2242    fc(catch bad_guards_2(#{a=>0,b=>0}, [])),
2243    fc(catch bad_guards_2(#{a=>0,b=>0}, [x])),
2244    fc(catch bad_guards_2(not_a_map, [x])),
2245    fc(catch bad_guards_2(42, [x])),
2246
2247    fc(catch bad_guards_3(#{a=>0,b=>0}, [])),
2248    fc(catch bad_guards_3(#{a=>0,b=>0}, [x])),
2249    fc(catch bad_guards_3(not_a_map, [x])),
2250    fc(catch bad_guards_3(42, [x])),
2251
2252    fc(catch bad_guards_4()),
2253
2254    {0,undefined} = bad_guards_5(id(<<>>), id(undefined)),
2255
2256    ok.
2257
2258%% beam_bool used to produce GC BIF instructions whose
2259%% Live operands included uninitialized registers.
2260
2261bad_guards_1(X, [_]) when {{X}}, -X ->
2262    ok.
2263
2264bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) ->
2265    ok.
2266
2267%% beam_type used to produce an GC BIF instruction whose Live operand
2268%% included uninitialized registers.
2269
2270bad_guards_3(M, [_]) when is_map(M) andalso M#{a := 0, b => 0}, length(M) ->
2271    ok.
2272
2273%% v3_codegen would generate a jump to the failure label, but
2274%% without initializing x(0). The code at the failure label expected
2275%% x(0) to be initialized.
2276
2277bad_guards_4() when not (error#{}); {not 0.0} -> freedom.
2278
2279%% The JIT used to segfault when a guard rem instruction failed
2280%% with badarith AND a bif had been called just before it.
2281bad_guards_5(A, B) ->
2282    {byte_size(A), undefined = bad_guards_5_1(B)}.
2283bad_guards_5_1(A) when is_integer(A rem 255) ->
2284    A rem 255;
2285bad_guards_5_1(_) ->
2286    undefined.
2287
2288%% Building maps in a guard in a 'catch' would crash v3_codegen.
2289
2290guard_in_catch(_Config) ->
2291    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{}),
2292    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(#{a=>b}),
2293    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_1(atom),
2294
2295    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{}),
2296    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(#{a=>b}),
2297    {'EXIT',{if_clause,_}} = do_guard_in_catch_map_2(atom),
2298
2299    {'EXIT',{if_clause,_}} = (catch do_guard_in_catch_map_3()),
2300
2301    {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(42),
2302    {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(<<1,2,3>>),
2303    {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(atom),
2304    {'EXIT',{if_clause,_}} = do_guard_in_catch_bin(#{}),
2305
2306    ok.
2307
2308do_guard_in_catch_map_1(From) ->
2309    catch
2310	if
2311	    From#{[] => sufficient} ->
2312		saint
2313	end.
2314
2315do_guard_in_catch_map_2(From) ->
2316    catch
2317	if
2318	    From#{From => sufficient} ->
2319		saint
2320	end.
2321
2322do_guard_in_catch_map_3() ->
2323    try
2324	if [] -> solo end
2325    catch
2326	Friendly when Friendly#{0 => []} -> minutes
2327    after
2328	membership
2329    end.
2330
2331do_guard_in_catch_bin(From) ->
2332    %% Would not crash v3_codegen, but there would be an unnecessary
2333    %% 'move' to a Y register.
2334    catch
2335	if
2336	    <<From:32>> ->
2337		saint
2338	end.
2339
2340%%%
2341%%% The beam_bool pass has been eliminated. Here are the tests from
2342%%% beam_bool_SUITE, as well as new tests to test the new beam_ssa_bool
2343%%% module.
2344%%%
2345
2346beam_bool_SUITE(_Config) ->
2347    before_and_inside_if(),
2348    scotland(),
2349    y_registers(),
2350    protected(),
2351    maps(),
2352    cover_shortcut_branches(),
2353    wrong_order(),
2354    megaco(),
2355    looks_like_a_guard(),
2356    fail_in_guard(),
2357    in_catch(),
2358    recv_semi(),
2359    andalso_repeated_var(),
2360    erl1246(),
2361    erl1253(),
2362    erl1384(),
2363    gh4788(),
2364    beam_ssa_bool_coverage(),
2365    ok.
2366
2367before_and_inside_if() ->
2368    no = before_and_inside_if([a], [b], delete),
2369    no = before_and_inside_if([a], [b], x),
2370    no = before_and_inside_if([a], [], delete),
2371    no = before_and_inside_if([a], [], x),
2372    no = before_and_inside_if([], [], delete),
2373    yes = before_and_inside_if([], [], x),
2374    yes = before_and_inside_if([], [b], delete),
2375    yes = before_and_inside_if([], [b], x),
2376
2377    {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
2378    {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
2379    {ch1,ch2} = before_and_inside_if_2([a], [], blah),
2380    {ch1,ch2} = before_and_inside_if_2([a], [], xx),
2381    {no,no} = before_and_inside_if_2([], [b], blah),
2382    {no,no} = before_and_inside_if_2([], [b], xx),
2383    {ch1,no} = before_and_inside_if_2([], [], blah),
2384    {no,ch2} = before_and_inside_if_2([], [], xx),
2385    ok.
2386
2387%% Thanks to Simon Cornish and Kostis Sagonas.
2388%% Used to crash beam_bool.
2389before_and_inside_if(XDo1, XDo2, Do3) ->
2390    Do1 = (XDo1 =/= []),
2391    Do2 = (XDo2 =/= []),
2392    if
2393	%% This expression occurs in a try/catch (protected)
2394	%% block, which cannot refer to variables outside of
2395	%% the block that are boolean expressions.
2396	Do1 =:= true;
2397	Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
2398	    no;
2399       true ->
2400	    yes
2401    end.
2402
2403%% Thanks to Simon Cornish.
2404%% Used to generate code that would not set {y,0} on
2405%% all paths before its use (and therefore fail
2406%% validation by the beam_validator).
2407before_and_inside_if_2(XDo1, XDo2, Do3) ->
2408    Do1    = (XDo1 =/= []),
2409    Do2    = (XDo2 =/= []),
2410    CH1 = if Do1 == true;
2411	     Do1 == false,Do2==false,Do3 == blah ->
2412		  ch1;
2413	     true ->
2414		  no
2415	  end,
2416    CH2 = if Do1 == true;
2417	     Do1 == false,Do2==false,Do3 == xx ->
2418		  ch2;
2419	     true ->
2420		  no
2421	  end,
2422    {CH1,CH2}.
2423
2424
2425%% beam_bool would remove the initialization of {y,0}.
2426%% (Thanks to Thomas Arts and QuickCheck.)
2427
2428scotland() ->
2429    million = do_scotland(placed),
2430    {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
2431    {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
2432    {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
2433    ok.
2434
2435do_scotland(Echo) ->
2436  found(case Echo of
2437	    Echo when true; Echo, Echo, Echo ->
2438		Echo;
2439	    echo ->
2440		[]
2441	end,
2442	Echo = placed).
2443
2444found(_, _) -> million.
2445
2446
2447%% ERL-143: beam_bool could not handle Y registers as a destination.
2448y_registers() ->
2449    {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
2450    {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
2451
2452    {not_ok,true} = potter([]),
2453    {ok,false} = potter([{encoding,any}]),
2454
2455    ok.
2456
2457%% Thanks to Quickcheck.
2458baker(Baker) ->
2459    (valentine == Baker) +
2460	case Baker of
2461	    Baker when Baker; Baker ->
2462		Baker;
2463	    Baker ->
2464		[]
2465	end.
2466
2467%% Thanks to Jose Valim.
2468potter(Modes) ->
2469    Raw = lists:keyfind(encoding, 1, Modes) == false,
2470    Final = case Raw of
2471		X when X == false; X == nil -> ok;
2472		_ -> not_ok
2473	    end,
2474    {Final,Raw}.
2475
2476protected() ->
2477    {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
2478
2479    {{true}} = welcome({perfect, true}),
2480    {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
2481    ok.
2482
2483photographs({_Violation, surprise, Deep}, opinions) ->
2484    {if
2485	 0; "here", Deep ->
2486	     Deep = Deep
2487     end}.
2488
2489welcome({perfect, Profit}) ->
2490    if
2491	Profit, Profit, Profit; 0 ->
2492	    {id({Profit})}
2493    end.
2494
2495maps() ->
2496    ok = evidence(#{0 => 42}).
2497
2498%% Cover handling of put_map in in split_block_label_used/2.
2499evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
2500    ok.
2501
2502cover_shortcut_branches() ->
2503    ok = cover_shortcut_branches({r1}, 0, 42, false),
2504    ok = cover_shortcut_branches({r1}, 42, 42, true),
2505    error = cover_shortcut_branches({r1}, same, same, false),
2506    error = cover_shortcut_branches({r1}, x, y, true),
2507    error = cover_shortcut_branches({r2}, 0, 42, false),
2508    error = cover_shortcut_branches({}, 0, 42, false),
2509    error = cover_shortcut_branches(not_tuple, 0, 42, false),
2510    ok.
2511
2512cover_shortcut_branches(St, X, Y, Z) ->
2513    if
2514        %% The ((Y =:= X) =:= Z) part will test handling of a comparison
2515        %% operator followed by a one-way `br`.
2516        ((element(1, St) =:= r1) orelse fail) and ((Y =:= X) =:= Z) ->
2517            ok;
2518        true ->
2519            error
2520    end.
2521
2522wrong_order() ->
2523    ok = wrong_order(repeat_until_fail, true),
2524    ok = wrong_order(repeat_until_fail, whatever),
2525    error = wrong_order(repeat_until_fail, false),
2526    error = wrong_order(nope, true),
2527    ok.
2528
2529wrong_order(RepeatType, Mode) ->
2530    Parallel = Mode =/= false,
2531    RepeatStop = RepeatType =:= repeat_until_fail,
2532    if
2533        Parallel andalso RepeatStop ->
2534            ok;
2535        true ->
2536            error
2537    end.
2538
2539megaco() ->
2540    ok = megaco('NULL', 0),
2541    ok = megaco('NULL', 7),
2542    ok = megaco('NULL', 15),
2543    ok = megaco('NULL', asn1_NOVALUE),
2544    ok = megaco(asn1_NOVALUE, 0),
2545    ok = megaco(asn1_NOVALUE, 7),
2546    ok = megaco(asn1_NOVALUE, 15),
2547    ok = megaco(asn1_NOVALUE, asn1_NOVALUE),
2548
2549    error = megaco(bad, 0),
2550    error = megaco(bad, 7),
2551    error = megaco(bad, 15),
2552    error = megaco(bad, asn1_NOVALUE),
2553
2554    error = megaco('NULL', not_integer),
2555    error = megaco('NULL', -1),
2556    error = megaco('NULL', 16),
2557    error = megaco(asn1_NOVALUE, not_integer),
2558    error = megaco(asn1_NOVALUE, -1),
2559    error = megaco(asn1_NOVALUE, 16),
2560
2561    error = megaco(bad, bad),
2562    error = megaco(bad, -1),
2563    error = megaco(bad, 42),
2564
2565    ok.
2566
2567megaco(Top, SelPrio)
2568  when (Top =:= 'NULL' orelse Top =:= asn1_NOVALUE) andalso
2569       ((is_integer(SelPrio) andalso ((0 =< SelPrio) and (SelPrio =< 15))) orelse
2570	SelPrio =:= asn1_NOVALUE) ->
2571    ok;
2572megaco(_, _) ->
2573    error.
2574
2575%% ERL-1054.
2576looks_like_a_guard() ->
2577    ok = looks_like_a_guard(0),
2578    ok = looks_like_a_guard(1),
2579    ok.
2580
2581looks_like_a_guard(N) ->
2582    GuessPosition = id(42),
2583    %% The matching of `true` would look like a guard to
2584    %% beam_ssa_bool. The optimized code would not be safe.
2585    case {1 >= N, GuessPosition == 0} of
2586        {true, _} -> ok;
2587        {_, true} -> ok;
2588        _ -> looks_like_a_guard(N)
2589    end.
2590
2591-record(fail_in_guard, {f}).
2592fail_in_guard() ->
2593    false = struct_or_map(a, "foo"),
2594    false = struct_or_map(a, foo),
2595    false = struct_or_map(#{}, "foo"),
2596    true = struct_or_map(#{}, foo),
2597
2598    false = (fun() when whatever =/= (program andalso []) -> true;
2599                () -> false
2600             end)(),
2601    false = if whatever =/= (program orelse []) -> true;
2602               true -> false
2603            end,
2604
2605    %% Would crash the compiler if optimizing passes
2606    %% were disabled.
2607    error = if
2608                0.1 orelse "VZ", 42 -> ok;
2609                true -> error
2610            end,
2611    error = (fun() when 3.14; <<[]:(ceil($D))>> -> ok;
2612               () -> error
2613            end)(),
2614    error = fun() when eye; ""#fail_in_guard.f andalso #{[] => true and false} ->
2615                    ok;
2616               () ->
2617                    error
2618            end(),
2619    error = fun() when (0 #fail_in_guard.f)#fail_in_guard.f -> ok;
2620               () -> error
2621            end(),
2622    error = fun() when 42; <<0.5,0:(element(true, false))>> ->
2623                    a = b;
2624               () -> error
2625            end(),
2626
2627    ok.
2628
2629%% ERL-1183. If Name is not an atom, the `fail` atom must cause the
2630%% entire guard to fail.
2631struct_or_map(Arg, Name) when
2632      (is_map(Arg) andalso (is_atom(Name) orelse fail) andalso
2633       is_map_key(struct, Arg)) orelse is_map(Arg) -> true;
2634struct_or_map(_Arg, _Name) ->
2635    false.
2636
2637in_catch() ->
2638    ok = in_catch(true),
2639    {'EXIT',{{case_clause,false},[_|_]}} = in_catch(false),
2640    {'EXIT',{badarg,[_|_]}} = in_catch(any),
2641    ok.
2642
2643in_catch(V) ->
2644    catch
2645        case false or V of
2646            true -> ok
2647        end.
2648
2649recv_semi() ->
2650    timeout = id(receive
2651                     ok when home; <<(m#{}):false>> ->
2652                         ok
2653                 after 0 ->
2654                         timeout
2655                 end).
2656
2657andalso_repeated_var() ->
2658    ok = andalso_repeated_var(true),
2659    error = andalso_repeated_var(false),
2660    error = andalso_repeated_var([not_boolean]),
2661    ok.
2662
2663andalso_repeated_var(B) when B andalso B -> ok;
2664andalso_repeated_var(_) -> error.
2665
2666-record(erl1246, {tran_stat = 0}).
2667
2668erl1246() ->
2669    false = erl1246(#erl1246{tran_stat = 0}, #{cid => 1131}),
2670    false = erl1246(#erl1246{tran_stat = 12}, #{cid => 1131}),
2671    false = erl1246(#erl1246{tran_stat = 12}, #{cid => 9502}),
2672    true = erl1246(#erl1246{tran_stat = 0}, #{cid => 9502}),
2673    ok.
2674
2675erl1246(Rec, #{cid := CollID}) ->
2676    {GiftCollID, _} = erl1246_conf(gift_coll),
2677    IsTranStat = Rec#erl1246.tran_stat =:= erl1246_conf(transform_id),
2678    if
2679        %% Optimization of 'not' in a guard was broken.
2680        CollID =:= GiftCollID andalso not IsTranStat ->
2681            true;
2682        true ->
2683            false
2684    end.
2685
2686erl1246_conf(gift_coll) -> {9502, {112, 45}};
2687erl1246_conf(transform_id) -> 12;
2688erl1246_conf(_) -> undefined.
2689
2690erl1253() ->
2691    ok = erl1253_orelse_false(a, a, any),
2692    ok = erl1253_orelse_false(a, a, true),
2693    ok = erl1253_orelse_false(a, a, false),
2694    error = erl1253_orelse_false(a, b, any),
2695    error = erl1253_orelse_false(a, b, true),
2696    ok = erl1253_orelse_false(a, b, false),
2697
2698    ok = erl1253_orelse_true(a, a, any),
2699    ok = erl1253_orelse_true(a, a, true),
2700    ok = erl1253_orelse_true(a, a, false),
2701    error = erl1253_orelse_true(a, b, any),
2702    ok = erl1253_orelse_true(a, b, true),
2703    error = erl1253_orelse_true(a, b, false),
2704
2705    error = erl1253_andalso_false(a, a, any),
2706    error = erl1253_andalso_false(a, a, true),
2707    ok = erl1253_andalso_false(a, a, false),
2708    error = erl1253_andalso_false(a, b, any),
2709    error = erl1253_andalso_false(a, b, true),
2710    error = erl1253_andalso_false(a, b, false),
2711
2712    error = erl1253_andalso_true(a, a, any),
2713    ok = erl1253_andalso_true(a, a, true),
2714    error = erl1253_andalso_true(a, a, false),
2715    error = erl1253_andalso_true(a, b, any),
2716    error = erl1253_andalso_true(a, b, true),
2717    error = erl1253_andalso_true(a, b, false),
2718
2719    ok.
2720
2721erl1253_orelse_false(X, Y, Z) ->
2722    Res = erl1253_orelse_false_1(X, Y, Z),
2723    Res = erl1253_orelse_false_2(X, Y, Z),
2724    Res = erl1253_orelse_false_3(X, Y, Z).
2725
2726erl1253_orelse_false_1(X, Y, Z) ->
2727    Bool = Z =:= false,
2728    if
2729        X =:= Y orelse Bool -> ok;
2730        true -> error
2731    end.
2732
2733erl1253_orelse_false_2(X, Y, Z) ->
2734    Bool = Z =:= false,
2735    if
2736        Bool orelse X =:= Y -> ok;
2737        true -> error
2738    end.
2739
2740erl1253_orelse_false_3(X, Y, Z) ->
2741    Bool1 = X =:= Y,
2742    Bool2 = Z =:= false,
2743    if
2744        Bool1 orelse Bool2 -> ok;
2745        true -> error
2746    end.
2747
2748erl1253_orelse_true(X, Y, Z) ->
2749    Res = erl1253_orelse_true_1(X, Y, Z),
2750    Res = erl1253_orelse_true_2(X, Y, Z),
2751    Res = erl1253_orelse_true_3(X, Y, Z).
2752
2753erl1253_orelse_true_1(X, Y, Z)   ->
2754    Bool = Z =:= true,
2755    if
2756        X =:= Y orelse Bool -> ok;
2757        true -> error
2758    end.
2759
2760erl1253_orelse_true_2(X, Y, Z) ->
2761    Bool = Z =:= true,
2762    if
2763        Bool orelse X =:= Y -> ok;
2764        true -> error
2765    end.
2766
2767erl1253_orelse_true_3(X, Y, Z)   ->
2768    Bool1 = X =:= Y,
2769    Bool2 = Z =:= true,
2770    if
2771        Bool1 orelse Bool2 -> ok;
2772        true -> error
2773    end.
2774
2775erl1253_andalso_false(X, Y, Z) ->
2776    Res = erl1253_andalso_false_1(X, Y, Z),
2777    Res = erl1253_andalso_false_2(X, Y, Z),
2778    Res = erl1253_andalso_false_3(X, Y, Z).
2779
2780erl1253_andalso_false_1(X, Y, Z) ->
2781    Bool = Z =:= false,
2782    if
2783        X =:= Y andalso Bool -> ok;
2784        true -> error
2785    end.
2786
2787erl1253_andalso_false_2(X, Y, Z) ->
2788    Bool1 = X =:= Y,
2789    Bool2 = Z =:= false,
2790    if
2791        Bool1 andalso Bool2 -> ok;
2792        true -> error
2793    end.
2794
2795erl1253_andalso_false_3(X, Y, Z) ->
2796    Bool1 = X =:= Y,
2797    Bool2 = Z =:= false,
2798    if
2799        Bool1 andalso Bool2 -> ok;
2800        true -> error
2801    end.
2802
2803erl1253_andalso_true(X, Y, Z) ->
2804    Res = erl1253_andalso_true_1(X, Y, Z),
2805    Res = erl1253_andalso_true_2(X, Y, Z),
2806    Res = erl1253_andalso_true_3(X, Y, Z).
2807
2808erl1253_andalso_true_1(X, Y, Z) ->
2809    Bool = Z =:= true,
2810    if
2811        X =:= Y andalso Bool -> ok;
2812        true -> error
2813    end.
2814
2815erl1253_andalso_true_2(X, Y, Z) ->
2816    Bool = Z =:= true,
2817    if
2818        Bool andalso X =:= Y-> ok;
2819        true -> error
2820    end.
2821
2822erl1253_andalso_true_3(X, Y, Z) ->
2823    Bool1 = X =:= Y,
2824    Bool2 = Z =:= true,
2825    if
2826        Bool1 andalso Bool2 -> ok;
2827        true -> error
2828    end.
2829
2830erl1384() ->
2831    gurka = erl1384_1(id(a)),
2832    gaffel = erl1384_1(id(b)),
2833    ok.
2834
2835erl1384_1(V) ->
2836    case {id(false), V =/= a} of
2837        {true, true} -> not_reachable;
2838        {_, false} -> gurka;
2839        _ -> gaffel
2840    end.
2841
2842gh4788() ->
2843    ok = do_gh4788(id(0)),
2844    ok = do_gh4788(id(1)),
2845    ok = do_gh4788(id(undefined)),
2846    lt_0_or_undefined = catch do_gh4788(id(-1)),
2847    ok.
2848
2849do_gh4788(N) ->
2850    %% beam_ssa_bool would do an unsafe optimization when run after
2851    %% the beam_ssa_share pass.
2852    case {N >= 0, N == undefined} of
2853        {true, _} -> ok;
2854        {_, true} -> ok;
2855        _ -> throw(lt_0_or_undefined)
2856    end,
2857    ok.
2858
2859beam_ssa_bool_coverage() ->
2860    {"*","abc"} = collect_modifiers("abc*", []),
2861    error = beam_ssa_bool_coverage_1(true),
2862    ok.
2863
2864collect_modifiers([H | T], Buffer)
2865    when (H >= $a andalso H =< $z) or
2866         (H >= $A andalso H =< $Z) ->
2867    collect_modifiers(T, [H | Buffer]);
2868collect_modifiers(Rest, Buffer) ->
2869    {Rest, lists:reverse(Buffer)}.
2870
2871beam_ssa_bool_coverage_1(V) when V andalso 0, tuple_size(0) ->
2872    ok;
2873beam_ssa_bool_coverage_1(_) ->
2874    error.
2875
2876%%%
2877%%% End of beam_bool_SUITE tests.
2878%%%
2879
2880repeated_type_tests(_Config) ->
2881    binary = repeated_type_test(<<42>>),
2882    bitstring = repeated_type_test(<<1:1>>),
2883    other = repeated_type_test(atom),
2884    ok.
2885
2886repeated_type_test(T) ->
2887    %% Test for a bug in beam_ssa_dead.
2888    if is_bitstring(T) ->
2889            if is_binary(T) ->                  %This test would be optimized away.
2890                    binary;
2891               true ->
2892                    bitstring
2893            end;
2894       true ->
2895            other
2896    end.
2897
2898%% ERL-1179: The result of '=/=' would be flipped if it was used after being
2899%% branched on.
2900use_after_branch(_Config) ->
2901    {false, gaffel} = use_after_branch_1(foo),
2902    {true, gurka} = use_after_branch_1(bar),
2903    ok.
2904
2905use_after_branch_1(A) ->
2906    Boolean = A =/= foo,
2907    case Boolean of
2908        true -> id(something);
2909        false -> id(other)
2910    end,
2911    case Boolean of
2912        true -> {id(Boolean), gurka};
2913        false -> {id(Boolean), gaffel}
2914    end.
2915
2916%% Call this function to turn off constant propagation.
2917id(I) -> I.
2918
2919check(F, Result) ->
2920    case F() of
2921	Result -> ok;
2922	Other ->
2923	    io:format("Expected: ~p\n", [Result]),
2924	    io:format("     Got: ~p\n", [Other]),
2925	    ct:fail(check_failed)
2926    end.
2927
2928fc({'EXIT',{function_clause,_}}) -> ok;
2929fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= guard_inline_SUITE -> ok.
2930