aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_floats.erl42
1 files changed, 33 insertions, 9 deletions
diff --git a/lib/hipe/test/basic_SUITE_data/basic_floats.erl b/lib/hipe/test/basic_SUITE_data/basic_floats.erl
index c49ac3946e..eec175075a 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_floats.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_floats.erl
@@ -7,6 +7,7 @@
-module(basic_floats).
-export([test/0]).
+-export([test_fmt_double_fpe_leak/0]). % suppress the unused warning
test() ->
ok = test_arith_ops(),
@@ -16,6 +17,7 @@ test() ->
ok = test_catch_bad_fp_arith(),
ok = test_catch_fp_conv(),
ok = test_fp_with_fp_exceptions(),
+ %% ok = test_fmt_double_fpe_leak(), % this requires printing
ok.
%%--------------------------------------------------------------------
@@ -47,8 +49,8 @@ negate(X) ->
%%--------------------------------------------------------------------
test_fp_ebb() ->
- 1.0 = foo(2*math:pi()),
- 1.0 = bar(2*math:pi()),
+ 1.0 = foo(2 * math:pi()),
+ 1.0 = bar(2 * math:pi()),
ok.
foo(X) ->
@@ -123,7 +125,7 @@ big_int_arith(I) when is_integer(I) ->
big_const_float(F) ->
I = trunc(F),
badarith = try (1/(2*I)) catch error:Err -> Err end,
- _Ignore = 2/I,
+ _ = 2/I,
{'EXIT', _} = (catch 4/(2*I)),
ok.
@@ -133,14 +135,14 @@ big_const_float(F) ->
test_fp_with_fp_exceptions() ->
0.0 = math:log(1.0),
- badarith = try math:log(minus_one_float()) catch error:E1 -> E1 end,
+ badarith = try math:log(float_minus_one()) catch error:E1 -> E1 end,
0.0 = math:log(1.0),
- badarith = try math:log(zero_float()) catch error:E2 -> E2 end,
+ badarith = try math:log(float_zero()) catch error:E2 -> E2 end,
0.0 = math:log(1.0),
%% An old-fashioned exception here just so as to test this case also
- {'EXIT',_} = (catch fp_mult(3.23e133, 3.57e257)),
+ {'EXIT', _} = (catch fp_mult(3.23e133, 3.57e257)),
0.0 = math:log(1.0),
- badarith = try fp_div(5.0,0.0) catch error:E3 -> E3 end,
+ badarith = try fp_div(5.0, 0.0) catch error:E3 -> E3 end,
0.0 = math:log(1.0),
ok.
@@ -151,6 +153,28 @@ fp_div(X, Y) -> X / Y.
%% The following two function definitions appear here just to shut
%% off 'expression will fail with a badarg' warnings from the compiler
-zero_float() -> 0.0.
+float_zero() -> 0.0.
-minus_one_float() -> -1.0.
+float_minus_one() -> -1.0.
+
+%%--------------------------------------------------------------------
+%% Test that erl_printf_format.c:fmt_double() does not leak pending FP
+%% exceptions to subsequent code. This used to break x87 FP code on
+%% 32-bit x86. Based on a problem report from Richard Carlsson.
+
+test_fmt_double_fpe_leak() ->
+ test_fmt_double_fpe_leak(float_zero(), int_two()),
+ ok.
+
+%% We need the specific sequence of erlang:display/1 on a float that
+%% triggers faulting ops in fmt_double() followed by a simple FP BIF.
+%% We also need to repeat this at least three times.
+test_fmt_double_fpe_leak(X, Y) ->
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X), _ = math:log10(Y),
+ erlang:display(X),
+ math:log10(Y).
+
+int_two() -> 2.