-module(guards). -compile([export_all]). -record(r, {f}). %% This is the reduced original test (no warnings) -define(g1(A), ((A#r.f =:= a) orelse (A#r.f =:= b))). t1(A) when ?g1(A) -> ok; t1(A) when not ?g1(A) -> ko. %% This should emit a warning t1_s(A) when ?g1(A) -> ok. t1_s_a() -> t1_s(#r{f=c}). %% Same as t1 with 'or' instead of 'orelse' (no warnings) -define(g2(A), ((A#r.f =:= a) or (A#r.f =:= b))). t2(A) when ?g2(A) -> ok; t2(A) when not ?g2(A) -> ko. %% This should emit a warning t2_s(A) when ?g2(A) -> ok. t2_s_a() -> t2_s(#r{f=c}). %% This could probably give a warning -define(g3(A), (A#r.f =:= a orelse is_atom(A))). t3(A) when ?g3(A) -> ok; t3(A) when not ?g3(A) -> ko. %% This could probably give a warning as well -define(g4(A), ((A#r.f =:= a) or is_atom(A))). t4(A) when ?g4(A) -> ok; t4(A) when not ?g4(A) -> ko. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Some shots in the dark on guard abuse %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Should give a warning t5(A) when is_atom(A) and is_integer(A) -> never. %% Should give the same warning as t5 t6(A) when is_atom(A) andalso is_integer(A) -> never. %% Should give a warning t7(A) when is_atom(A) or is_integer(A) -> ok. at7(42) -> t7(42); at7('a') -> t7('a'); at7({42}) -> t7({42}). %% Should give a warning t8(A) when is_atom(A) orelse is_integer(A) -> ok. at8(42) -> t8(42); at8('a') -> t8('a'); at8({42}) -> t8({42}). %% Should give a warning t9(A) when is_atom(A) orelse is_integer(A) -> ok; t9(A) when is_atom(A) -> redundant. %% Should give a warning t10(A) when is_atom(A) or is_integer(A) -> ok; t10(A) when is_atom(A) -> redundant. %% Should give a warning t11(A, B) when is_atom(A) and is_atom(B) -> case {is_atom(A), is_atom(B)} of {true, true} -> ok; _ -> redundant end. %% Should give a warning t12(A, B) when is_atom(A) andalso is_atom(B) -> case {is_atom(A), is_atom(B)} of {true, true} -> ok; _ -> redundant end. %% Should give two warnings t13(A, B) when is_atom(A) or is_atom(B) -> case {is_atom(A), is_atom(B)} of {true , true } -> ok; {true , false} -> ok; {false, true } -> ok; {false, false} -> never; {_ , _ } -> even_more_never end. %% Should give two warnings t14(A, B) when is_atom(A) orelse is_atom(B) -> case {is_atom(A), is_atom(B)} of {true , true } -> ok; {true , false} -> ok; {false, true } -> ok; {false, false} -> never; {_ , _ } -> even_more_never end. %% Should give two warnings t15(A) when ((A =:= a) or (A =:= b)) and ((A =:= b) or (A =:= c)) -> ok. t15_a() -> t15(a), t15(b), t15(c). %% Should give two warnings t16(A) when ((A =:= a) orelse (A =:= b)) andalso ((A =:= b) orelse (A =:= c)) -> ok. t16_a() -> t16(a), t16(b), t16(c).