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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
%%% -*- erlang-indent-level: 2 -*-
%%%-------------------------------------------------------------------
%%% Author: Kostis Sagonas
%%%
%%% Contains code examples that exhibited crashes in the HiPE compiler.
%%%-------------------------------------------------------------------
-module(basic_issues_hipe).
-export([test/0]).
%% functions that need to be exported so that they are retained.
-export([auth/4]).
test() ->
ok = test_dominance_trees(),
ok = test_merged_const(),
ok = test_var_pair(),
ok = test_bif_fails(),
ok = test_find_catches(),
ok = test_heap_allocate_trim(),
ok.
%%--------------------------------------------------------------------
%% This is taken from a file sent to us by Martin Bjorklund @ Nortel
%% on 14th November 2004. The problem was in the SSA unconvert pass.
%%
%% No tests here; we simply check that the HiPE compiler does not go
%% into an infinite loop when compiling strange functions like this.
%%--------------------------------------------------------------------
auth(_, A, B, C) ->
auth(A, B, C, []).
%%--------------------------------------------------------------------
%% Exposed a crash in the generation of dominance trees used in SSA.
%%--------------------------------------------------------------------
-record(state, {f}).
test_dominance_trees() ->
{ok, true} = doit(true, #state{f = true}),
ok.
doit(Foo, S) ->
Fee = case Foo of
Bar when Bar == S#state.f; Bar == [] -> true;
_ -> false
end,
{ok, Fee}.
%%--------------------------------------------------------------------
%% Checks that the merging of constants in the constant table uses the
%% appropriate comparison function for this.
%%--------------------------------------------------------------------
test_merged_const() ->
Const1 = {'', 1.0000},
Const2 = {'', 1},
match(Const1, Const2).
match(A, A) ->
error;
match(_A, _B) ->
ok.
%%--------------------------------------------------------------------
%% Checks that the HiPE compiler does not get confused by constant
%% data structures similar to the internal compiler data structures.
%%--------------------------------------------------------------------
test_var_pair() ->
ok = var_pair([gazonk]).
var_pair([_|_]) ->
var_pair({var, some_atom});
var_pair(_) ->
ok.
%%--------------------------------------------------------------------
%% This module was causing the HiPE compiler to crash in January 2007.
%% The culprit was an "optimization" of the BEAM compiler: postponing
%% the save of x variables when BIFs cannot fail. This was fixed on
%% February 1st, by making the HiPE compiler use the same functions
%% as the BEAM compiler for deciding whether a BIF fails.
%%--------------------------------------------------------------------
test_bif_fails() ->
[42] = bif_fails_in_catch([42]),
true = bif_fails_in_try([42]),
ok.
bif_fails_in_catch(X) ->
case catch get(gazonk) of
_ -> X
end.
bif_fails_in_try(X) ->
try
true = X =/= []
catch
_ -> nil(X)
end.
nil(_) -> [].
%%--------------------------------------------------------------------
%% Test that resulted in a native code compiler crash in the code of
%% hipe_icode_exceptions:find_catches/1 when compiling find_catches/2.
%%--------------------------------------------------------------------
test_find_catches() ->
42 = find_catches(a, false),
ok.
find_catches(X, Y) ->
case X of
a when Y =:= true ->
catch id(X),
X;
b when Y =:= true ->
catch id(X),
X;
a ->
catch id(X),
42;
b ->
catch id(X),
42
end.
id(X) -> X.
%%--------------------------------------------------------------------
%% Date: Dec 28, 2007
%%
%% This is a test adapted from the file sent to the Erlang mailing
%% list by Eranga Udesh. The file did not compile because of problems
%% with the heap_allocate instruction and stack trimming.
%%--------------------------------------------------------------------
test_heap_allocate_trim() ->
{abandon, 42} = get_next_retry(a, 42),
ok.
get_next_retry(Error, Count) ->
case catch pair(retry_scheme, {Error, Count}) of
_ ->
case pair(Error, Count) of
_ -> {abandon, Count}
end
end.
pair(A, B) -> {A, B}.
|