Skip to content

Commit

Permalink
erts: Fix comparison of exact terms
Browse files Browse the repository at this point in the history
Comparison of exact terms could cause faulty term tests.
This was caused by a faulty (too small) internal type.

Symptom:

   -1 = erts_internal:cmp_term(2147483648,0). %% wrong

Correct:

   1 = erts_internal:cmp_term(2147483648,0).

Reported-by: Jesper Louis Andersen
  • Loading branch information
psyeugenic committed Mar 24, 2015
1 parent a48186e commit a1520d8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
2 changes: 1 addition & 1 deletion erts/emulator/beam/bif.c
Original file line number Diff line number Diff line change
Expand Up @@ -4659,7 +4659,7 @@ BIF_RETTYPE bump_reductions_1(BIF_ALIST_1)
}

BIF_RETTYPE erts_internal_cmp_term_2(BIF_ALIST_2) {
int res = CMP_TERM(BIF_ARG_1,BIF_ARG_2);
Sint res = CMP_TERM(BIF_ARG_1,BIF_ARG_2);

/* ensure -1, 0, 1 result */
if (res < 0) {
Expand Down
4 changes: 2 additions & 2 deletions erts/emulator/beam/erl_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ BIF_RETTYPE maps_merge_2(BIF_ALIST_2) {
Eterm *ks,*vs,*ks1,*vs1,*ks2,*vs2;
map_t *mp1,*mp2,*mp_new;
Uint n1,n2,i1,i2,need,unused_size=0;
int c = 0;
Sint c = 0;

mp1 = (map_t*)map_val(BIF_ARG_1);
mp2 = (map_t*)map_val(BIF_ARG_2);
Expand Down Expand Up @@ -798,7 +798,7 @@ int erts_validate_and_sort_map(map_t* mp)
Uint sz = map_get_size(mp);
Uint ix,jx;
Eterm tmp;
int c;
Sint c;

/* sort */

Expand Down
45 changes: 45 additions & 0 deletions erts/emulator/test/map_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
t_maps_without/1,

%% misc
t_erts_internal_order/1,
t_pdict/1,
t_ets/1,
t_dets/1,
Expand Down Expand Up @@ -96,6 +97,7 @@ all() -> [


%% Other functions
t_erts_internal_order,
t_pdict,
t_ets,
t_tracing
Expand Down Expand Up @@ -960,6 +962,49 @@ t_maps_without(_Config) ->


%% MISC

t_erts_internal_order(_Config) when is_list(_Config) ->

-1 = erts_internal:cmp_term(1,2),
1 = erts_internal:cmp_term(2,1),
0 = erts_internal:cmp_term(2,2),


-1 = erts_internal:cmp_term(1,a),
1 = erts_internal:cmp_term(a,1),
0 = erts_internal:cmp_term(a,a),

-1 = erts_internal:cmp_term(1,1.0),
1 = erts_internal:cmp_term(1.0,1),
0 = erts_internal:cmp_term(1.0,1.0),

-1 = erts_internal:cmp_term(1,1 bsl 65),
1 = erts_internal:cmp_term(1 bsl 65,1),
0 = erts_internal:cmp_term(1 bsl 65, 1 bsl 65),

-1 = erts_internal:cmp_term(1 bsl 65,float(1)),
1 = erts_internal:cmp_term(float(1),1 bsl 65),
-1 = erts_internal:cmp_term(1,float(1 bsl 65)),
1 = erts_internal:cmp_term(float(1 bsl 65),1),
0 = erts_internal:cmp_term(float(1 bsl 65), float(1 bsl 65)),

%% reported errors
-1 = erts_internal:cmp_term(0,2147483648),
0 = erts_internal:cmp_term(2147483648,2147483648),
1 = erts_internal:cmp_term(2147483648,0),

M = #{0 => 0,2147483648 => 0},
true = M =:= binary_to_term(term_to_binary(M)),

F1 = fun(_, _) -> 0 end,
F2 = fun(_, _) -> 1 end,
M0 = maps:from_list( [{-2147483649, 0}, {0,0}, {97, 0}, {false, 0}, {flower, 0}, {F1, 0}, {F2, 0}, {<<>>, 0}]),
M1 = maps:merge(M0, #{0 => 1}),
8 = maps:size(M1),
1 = maps:get(0,M1),
ok.


t_pdict(_Config) ->

put(#{ a => b, b => a},#{ c => d}),
Expand Down

0 comments on commit a1520d8

Please sign in to comment.