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
|
%% -*- erlang-indent-level: 2 -*-
%%--------------------------------------------------------------------
%% Contains three cases of bugs that were reported for R12B
%%--------------------------------------------------------------------
-module(bs_bugs_R12).
-export([test/0]).
test() ->
ok = test_beam_bug(),
ok = test_v3_codegen(),
ok = test_hipe_bug(),
ok.
%%--------------------------------
%% First test case: a bug in BEAM
%%--------------------------------
test_beam_bug() ->
lists:foreach(fun (_) -> ok = run(100) end, [1,2,3,4]).
%% For testing - runs scanner N number of times with same input
run(N) ->
lists:foreach(fun(_) -> scan(<<"region:whatever">>, []) end, lists:seq(1, N)).
scan(<<>>, TokAcc) ->
lists:reverse(['$thats_all_folks$' | TokAcc]);
scan(<<D, Z, Rest/binary>>, TokAcc)
when (D =:= $D orelse D =:= $d) and
((Z =:= $\s) or (Z =:= $() or (Z =:= $))) ->
scan(<<Z, Rest/binary>>, ['AND' | TokAcc]);
scan(<<D>>, TokAcc) when (D =:= $D) or (D =:= $d) ->
scan(<<>>, ['AND' | TokAcc]);
scan(<<N, Z, Rest/binary>>, TokAcc)
when (N =:= $N orelse N =:= $n) and
((Z =:= $\s) or (Z =:= $() or (Z =:= $))) ->
scan(<<Z, Rest/binary>>, ['NOT' | TokAcc]);
scan(<<C, Rest/binary>>, TokAcc) when (C >= $A) and (C =< $Z);
(C >= $a) and (C =< $z);
(C >= $0) and (C =< $9) ->
case Rest of
<<$:, R/binary>> ->
scan(R, [{'FIELD', C} | TokAcc]);
_ ->
scan(Rest, [{'KEYWORD', C} | TokAcc])
end.
%%---------------------------------------------------
%% Second test case: an internal error in v3_codegen
%% Reported by Mateusz Berezecki on 19/1/2008
%%---------------------------------------------------
-define(S, {42, 4242, 4711}).
-define(R, <<90,164,116>>).
test_v3_codegen() ->
_ = random:seed(?S),
B0 = gen_bit(120, <<>>),
B1 = set_bit(B0, 5),
B2 = clr_bit(B1, 5),
?R = set_bit(B2, 5),
ok.
gen_bit(0, Acc) -> Acc;
gen_bit(N, Acc) when is_integer(N), N > 0 ->
gen_bit(N-1, <<Acc/bits, (random:uniform(2)-1):1>>).
%% sets bit K in the Bitmap
set_bit(<<_Start:32/unsigned-little-integer, Bitmap/bits>>, K)
when is_integer(K), 0 < K, K =< bit_size(Bitmap) ->
Before = K-1,
After = bit_size(Bitmap) - K,
<<BeforeBits:Before/bits, _:1, AfterBits:After/bits>> = Bitmap,
<<BeforeBits/bits, 1:1, AfterBits/bits>>.
%% clears bit K in the Bitmap
clr_bit(<<_Start:32/unsigned-little-integer, Bitmap/bits>>, K)
when is_integer(K), 0 < K, K =< bit_size(Bitmap) ->
Before = K-1,
After = bit_size(Bitmap) - K,
<<BeforeBits:Before/bits, _:1, AfterBits:After/bits>> = Bitmap,
<<BeforeBits/bits, 0:1, AfterBits/bits>>.
%%--------------------------------------------------------------------
%% Third test case: a bug in HiPE
%% Reported by Steve Vinoski on 1/3/2008
%%
%% Below find the results of compiling and running the example code at
%% the bottom of this message. Using "c" to compile gives the right
%% answer; using "hipe:c" gives the wrong answer. This is with R12B-1.
%%
%% Within the code, on the second instance of function check/2 you'll
%% find a commented-out guard. If you uncomment the guard, then the
%% code works correctly with both "c" and "hipe:c".
%%---------------------------------------------------------------------
test_hipe_bug() ->
String = "2006/10/02/Linux-Journal",
Binary = list_to_binary(String),
StringToMatch = "200x/" ++ String ++ " ",
BinaryToMatch = list_to_binary(StringToMatch),
{ok, Binary} = match(BinaryToMatch),
ok.
match(<<>>) ->
nomatch;
match(Bin) ->
<<Front:16/binary, Tail/binary>> = Bin,
case Front of
<<_:3/binary,"x/",Y:4/binary,$/,M:2/binary,$/,D:2/binary,$/>> ->
case check(Tail) of
{ok, Match} ->
{ok, <<Y/binary,$/,M/binary,$/,D/binary,$/,Match/binary>>};
{nomatch, Skip} ->
{skip, Skip+size(Front)};
_ ->
wrong_answer
end;
_ ->
nomatch
end.
check(Bin) ->
check(Bin, 0).
check(<<$ , _/binary>>, 0) ->
{nomatch, 0};
check(Bin, Len) -> %when Len < size(Bin) ->
case Bin of
<<Front:Len/binary, $ , _/binary>> ->
{ok, Front};
<<_:Len/binary, $., _/binary>> ->
{nomatch, Len};
_ ->
check(Bin, Len+1)
end.
|