PageRenderTime 89ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/compiler/test/guard_SUITE.erl

https://github.com/bsmr-erlang/otp
Erlang | 2277 lines | 1761 code | 393 blank | 123 comment | 212 complexity | 03a13aa4038ad066497dd8c8125137f1 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, Apache-2.0

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

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

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