1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
-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).
|