aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/beam_type_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/test/beam_type_SUITE.erl')
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl64
1 files changed, 62 insertions, 2 deletions
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 86146c614f..d44fa60997 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -22,7 +22,8 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
integers/1,coverage/1,booleans/1,setelement/1,cons/1,
- tuple/1,record_float/1,binary_float/1,float_compare/1]).
+ tuple/1,record_float/1,binary_float/1,float_compare/1,
+ arity_checks/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -40,7 +41,8 @@ groups() ->
tuple,
record_float,
binary_float,
- float_compare
+ float_compare,
+ arity_checks
]}].
init_per_suite(Config) ->
@@ -64,6 +66,15 @@ integers(_Config) ->
college = do_integers_3(),
+ zero = do_integers_4(<<0:1>>, 0),
+ one = do_integers_4(<<1:1>>, 0),
+ other = do_integers_4(<<1:1>>, 2),
+
+ zero = do_integers_5(0, 0),
+ one = do_integers_5(0, 1),
+ two = do_integers_5(0, 2),
+ three = do_integers_5(0, 3),
+
ok.
do_integers_1(B0) ->
@@ -86,6 +97,30 @@ do_integers_3() ->
1 -> 0
end.
+do_integers_4(<<X:1,T/bits>>, C) ->
+ %% Binary matching gives the range 0-1 for X.
+ %% The range for `X bor C` is unknown. It must not be inherited
+ %% from X. (`X bor C` will reuse the register used for X.)
+ case X bor C of
+ 0 -> do_integers_4(T, C, zero);
+ 1 -> do_integers_4(T, C, one);
+ _ -> do_integers_4(T, C, other)
+ end.
+
+do_integers_4(_, _, Res) ->
+ Res.
+
+do_integers_5(X0, Y0) ->
+ %% X and Y will use the same register.
+ X = X0 band 1,
+ Y = Y0 band 3,
+ case Y of
+ 0 -> zero;
+ 1 -> one;
+ 2 -> two;
+ 3 -> three
+ end.
+
coverage(_Config) ->
{'EXIT',{badarith,_}} = (catch id(1) bsl 0.5),
{'EXIT',{badarith,_}} = (catch id(2.0) bsl 2),
@@ -171,6 +206,31 @@ do_float_compare(X) ->
_T -> Y > 0
end.
+arity_checks(_Config) ->
+ %% ERL-549: an unsafe optimization removed a test_arity instruction,
+ %% causing the following to return 'broken' instead of 'ok'.
+ ok = do_record_arity_check({rgb, 255, 255, 255, 1}),
+ ok = do_tuple_arity_check({255, 255, 255, 1}).
+
+-record(rgb, {r = 255, g = 255, b = 255}).
+
+do_record_arity_check(RGB) when
+ (element(2, RGB) >= 0), (element(2, RGB) =< 255),
+ (element(3, RGB) >= 0), (element(3, RGB) =< 255),
+ (element(4, RGB) >= 0), (element(4, RGB) =< 255) ->
+ if
+ element(1, RGB) =:= rgb, is_record(RGB, rgb) -> broken;
+ true -> ok
+ end.
+
+do_tuple_arity_check(RGB) when is_tuple(RGB),
+ (element(1, RGB) >= 0), (element(1, RGB) =< 255),
+ (element(2, RGB) >= 0), (element(2, RGB) =< 255),
+ (element(3, RGB) >= 0), (element(3, RGB) =< 255) ->
+ case RGB of
+ {255, _, _} -> broken;
+ _ -> ok
+ end.
id(I) ->
I.