aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/test/basic_SUITE_data/basic_bugs_beam.erl
blob: 0cf9a3cd4c8b533b9789547008702ff3e36c58b3 (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
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
%%% -*- erlang-indent-level: 2 -*-
%%%-------------------------------------------------------------------
%%% Author: Kostis Sagonas
%%%
%%% Contains code examples that exhibited bugs in the BEAM compiler.
%%%-------------------------------------------------------------------
-module(basic_bugs_beam).

-export([test/0]).

%% the following are needed for the test_catch_bug
-behaviour(gen_server).
-export([start_link/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

test() ->
  ok = test_fp_basic_blocks(),
  ok = test_catch_bug(),
  ok.

%%--------------------------------------------------------------------
%% Test which shows that BEAM's splitting of basic blocks should take
%% into account that arithmetic operations implemented as BIFs can
%% also cause exceptions and thus calls to BIFs should end basic blocks.
%%
%% Investigated and fixed in the beginning of April 2004.
%%--------------------------------------------------------------------

test_fp_basic_blocks() ->
  ok = t1(),
  ok = t2().

t1() ->
  X = (catch bad_arith1(2.0, 1.7)),
  case X of
    {'EXIT', {badarith, _}} ->
      ok;
    _ ->
      error
  end.

bad_arith1(X, Y) when is_float(X) ->
  X1 = X * 1.7e+308,
  X2 = X1 + 1.0,
  Y1 = Y * 2,
  {X2, Y1}.

%% Similarly, it is not kosher to have anything that can fail inside
%% the fp block since it will throw the exception before the fp
%% exception and we will get the same problems.

t2() ->
  case catch bad_arith2(2.0, []) of
    {'EXIT', {badarith, _}} ->
      ok;
    _ ->
      error
  end.

bad_arith2(X, Y) when is_float(X) ->
  X1 = X * 1.7e+308,
  Y1 = element(1, Y),
  {X1 + 1.0, Y1}.

%%--------------------------------------------------------------------
%% This was posted on the Erlang mailing list as a question:
%%
%%   Given the module below and the function call
%%     "catch_bug:start_link(foo)."
%%   from the Erlang shell, why does Erlang crash with "Catch not found"?
%%
%% The BEAM compiler was generating wrong code for this case;
%% this was fixed in R9C-0.  Native code generation was OK.
%%--------------------------------------------------------------------

test_catch_bug() ->
  ignore = start_link(foo),
  ok.

start_link(Param) ->
  gen_server:start_link(?MODULE, Param, []).

init(Param) ->
  process_flag(trap_exit, true),
  (catch begin
           dummy(Param),
           (catch exit(bar))
         end
  ),
  ignore.

dummy(_) -> ok.

%% gen_server callbacks below
handle_call(_Call, _From, State) -> {noreply, State}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.