diff options
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 4 | ||||
-rw-r--r-- | lib/compiler/test/beam_validator_SUITE.erl | 25 |
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 4c0cb6780a..16dba35adc 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -808,9 +808,11 @@ validate_bs_skip_utf(Fail, Ctx, Live, Vst0) -> %% A possibility for garbage collection must not occur between setelement/3 and %% set_tuple_element/3. %% +%% Note that #vst.current will be 'none' if the instruction is unreachable. +%% val_dsetel({move,_,_}, Vst) -> Vst; -val_dsetel({call_ext,3,{extfunc,erlang,setelement,3}}, #vst{current=St}=Vst) -> +val_dsetel({call_ext,3,{extfunc,erlang,setelement,3}}, #vst{current=#st{}=St}=Vst) -> Vst#vst{current=St#st{setelem=true}}; val_dsetel({set_tuple_element,_,_,_}, #vst{current=#st{setelem=false}}) -> error(illegal_context_for_set_tuple_element); diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 263fd2ca7e..ca85eef688 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -32,7 +32,8 @@ bad_bin_match/1,bad_dsetel/1, state_after_fault_in_catch/1,no_exception_in_catch/1, undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1, - map_field_lists/1,cover_bin_opt/1]). + map_field_lists/1,cover_bin_opt/1, + val_dsetel/1]). -include_lib("common_test/include/ct.hrl"). @@ -60,7 +61,7 @@ groups() -> freg_state,bad_bin_match,bad_dsetel, state_after_fault_in_catch,no_exception_in_catch, undef_label,illegal_instruction,failing_gc_guard_bif, - map_field_lists,cover_bin_opt]}]. + map_field_lists,cover_bin_opt,val_dsetel]}]. init_per_suite(Config) -> Config. @@ -546,3 +547,23 @@ beam_val(M) -> _ = [io:put_chars(beam_validator:format_error(E)) || E <- Errors], Errors. + +%%%------------------------------------------------------------------------- + +val_dsetel(_Config) -> + self() ! 13, + {'EXIT',{{try_clause,participating},_}} = (catch night(0)), + ok. + +night(Turned) -> + receive + 13 -> + try participating of engine -> 16 after false end + end, + %% The setelement/3 call is unreachable. + Turned(setelement(#{true => Turned}, + participating(Turned, "suit", 40, []), + Turned < Turned)), + ok. + +participating(_, _, _, _) -> ok. |