aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
blob: b280705a472b10411adc2c6628d9c314308fdd15 (plain) (blame)
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
%% -*- erlang-indent-level: 2 -*-
%%--------------------------------------------------------------------
-module(bs_pmatch_bugs).

-export([test/0]).

test() ->
  Bin = <<"123.123">>,
  <<49,50,51>> = lex_digits1(Bin, 1, []),
  <<49,50,51>> = lex_digits2(Bin, 1, []),
  ok = var_bind_bug(<<1, 2, 3, 4, 5, 6, 7, 8>>),
  ok.

%%--------------------------------------------------------------------
%% One of the lex_digits functions below gave incorrect results due to
%% incorrect pattern matching compilation of binaries by the byte code
%% compiler. Fixed by Bjorn Gustavsson on 5/3/2003.
%% --------------------------------------------------------------------
lex_digits1(<<$., Rest/binary>>, _Val, _Acc) ->
  Rest;
lex_digits1(<<N, Rest/binary>>, Val, Acc) when N >= $0, N =< $9 ->
  lex_digits1(Rest, Val * 10 + dec(N), Acc);
lex_digits1(_Other, _Val, _Acc) ->
  not_ok.

lex_digits2(<<N, Rest/binary>>,Val, Acc) when N >= $0, N =< $9 ->
  lex_digits2(Rest, Val * 10 + dec(N), Acc);
lex_digits2(<<$., Rest/binary>>, _Val, _Acc) ->
  Rest;
lex_digits2(_Other, _Val, _Acc) ->
  not_ok.

dec(A) ->
  A - $0.

%%--------------------------------------------------------------------
%% From: Bernard Duggan
%% Date: 11/3/2011
%%
%% I've just run into an interesting little bit of behaviour that
%% doesn't seem quite right.  erlc gives me the warning
%%
%%   43: Warning: this clause cannot match because a previous
%%		  clause at line 42 always matches
%%	 (line 42 is the "B -> wrong;" line).
%%
%% And sure enough, if you run test/0 you get 'wrong' back.
%%
%% That, in itself, is curious to me since by my understanding B should
%% be bound by the function header, and have no guarantee of being the
%% same as A.  I can't see how it could be unbound.
%%
%% Doubly curious, is that if I stop using B as the size specifier of C,
%% like this:
%%
%%   match(<<A:1/binary, B:8/integer, _C:1/binary, _Rest/binary>>) ->
%%
%% the warning goes away.  And the result becomes 'ok' (in spite of
%% nothing in the body having changed, and the only thing changing in
%% the header being the size of an unused variable at the tail of the
%% binary).
%%--------------------------------------------------------------------
var_bind_bug(<<A:1/binary, B:8/integer, _C:B/binary, _Rest/binary>>) ->
  case A of
    B -> wrong;
    _ -> ok
  end.