aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2017-10-02 15:55:09 +0200
committerErlang/OTP <[email protected]>2017-10-02 15:55:09 +0200
commit8a62e04d1283c450ad1fc440b57b87afca9f01d6 (patch)
tree4f8a520d17c233bbaad8c1602d93689f1f9267e2
parentf28ff5122f81c4104af14b1717b4bb9a49f537b8 (diff)
parent7715f437ab9a789e0500873b6002a49bfe69009c (diff)
downloadotp-8a62e04d1283c450ad1fc440b57b87afca9f01d6.tar.gz
otp-8a62e04d1283c450ad1fc440b57b87afca9f01d6.tar.bz2
otp-8a62e04d1283c450ad1fc440b57b87afca9f01d6.zip
Merge branch 'bjorn/erts/match-context/ERL-490/OTP-14640' into maint-20
* bjorn/erts/match-context/ERL-490/OTP-14640: Fix incorrect internal consistency failure for binary matching code
-rw-r--r--lib/compiler/src/beam_validator.erl6
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl38
2 files changed, 39 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 00901077d3..be8908dd6b 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1430,13 +1430,13 @@ merge_types(bool, {atom,A}) ->
merge_bool(A);
merge_types({atom,A}, bool) ->
merge_bool(A);
-merge_types(#ms{id=Id1,valid=B0,slots=Slots},
- #ms{id=Id2,valid=B1,slots=Slots}) ->
+merge_types(#ms{id=Id1,valid=B1,slots=Slots1},
+ #ms{id=Id2,valid=B2,slots=Slots2}) ->
Id = if
Id1 =:= Id2 -> Id1;
true -> make_ref()
end,
- #ms{id=Id,valid=B0 band B1,slots=Slots};
+ #ms{id=Id,valid=B1 band B2,slots=min(Slots1, Slots2)};
merge_types(T1, T2) when T1 =/= T2 ->
%% Too different. All we know is that the type is a 'term'.
term.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 0ec05456ec..2fe8cd0cff 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -39,7 +39,7 @@
match_string_opt/1,select_on_integer/1,
map_and_binary/1,unsafe_branch_caching/1,
bad_literals/1,good_literals/1,constant_propagation/1,
- parse_xml/1,get_payload/1]).
+ parse_xml/1,get_payload/1,num_slots_different/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -71,7 +71,7 @@ groups() ->
match_string_opt,select_on_integer,
map_and_binary,unsafe_branch_caching,
bad_literals,good_literals,constant_propagation,parse_xml,
- get_payload]}].
+ get_payload,num_slots_different]}].
init_per_suite(Config) ->
@@ -1524,6 +1524,40 @@ do_get_payload(ExtHdr) ->
<<_:13,_:35>> = ExtHdr#ext_header.ext_hdr_opts,
ExtHdrOptions.
+%% ERL-490
+num_slots_different(_Config) ->
+ Ts = [{<<"de">>, <<"default">>, <<"Remove">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Remove from list">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Remove from the list">>, <<"a">>},
+ {<<"de">>, <<"default">>, <<"Results">>, <<"Ergebnisse">>},
+ {<<"de">>, <<"default">>, <<"Reservatio">>, <<"a">>},
+ {<<"de">>, <<"navigation">>, <<"Results">>, <<"Ergebnisse">>},
+ {<<"de">>, <<"navigation">>, <<"Resources">>, <<"Ressourcen">>}],
+ _ = [{ok,Res} = lgettext(A, B, C) || {A,B,C,Res} <- Ts],
+
+ {'EXIT',_} = (catch lgettext(<<"d">>, <<"default">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext("", <<"default">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext(<<"de">>, <<"def">>, <<"Remove">>)),
+ {'EXIT',_} = (catch lgettext(<<"de">>, <<"default">>, <<"Res">>)),
+ ok.
+
+
+lgettext(<<"de">>, <<"default">>, <<"Remove">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Remove from list">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Remove from the list">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"default">>, <<"Results">>) ->
+ {ok, <<"Ergebnisse">>};
+lgettext(<<"de">>, <<"default">>, <<"Reservatio">>) ->
+ {ok, <<"a">>};
+lgettext(<<"de">>, <<"navigation">>, <<"Results">>) ->
+ {ok, <<"Ergebnisse">>};
+lgettext(<<"de">>, <<"navigation">>, <<"Resources">>) ->
+ {ok, <<"Ressourcen">>}.
+
+
check(F, R) ->
R = F().