From 31e231d813d8a15a937ebd5fbb71299ce1faf9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 15 Jan 2010 12:26:17 +0100 Subject: beam_validator: fix incorrect assumptions about GC guard BIFs The beam_validator pass incorrectly assumes that a GC guard BIF (such as length/1) may first do a garbage collection and then fail. That assumption is not correct (guards BIF only do garbage collection when it is known that the BIF call will succeed), and will cause the compiler to reject valid programs. Modify the beam_validator to assume that if the branch is taken for a gc_bif instruction, all registers are unchanged and no garbage collection has occurred. Also add a comment in the emulator about that assumption. --- lib/compiler/test/beam_validator_SUITE.erl | 36 +++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'lib/compiler/test/beam_validator_SUITE.erl') diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index ef8feb8a27..0659d5575e 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -28,7 +28,7 @@ freg_range/1,freg_uninit/1,freg_state/1, bin_match/1,bin_aligned/1,bad_dsetel/1, state_after_fault_in_catch/1,no_exception_in_catch/1, - undef_label/1,illegal_instruction/1]). + undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1]). -include("test_server.hrl"). @@ -52,13 +52,13 @@ all(suite) -> freg_range,freg_uninit,freg_state, bin_match,bin_aligned, bad_dsetel,state_after_fault_in_catch,no_exception_in_catch, - undef_label,illegal_instruction]. + undef_label,illegal_instruction,failing_gc_guard_bif]. beam_files(Config) when is_list(Config) -> ?line {ok,Cwd} = file:get_cwd(), ?line Parent = filename:dirname(Cwd), ?line Wc = filename:join([Parent,"*","*.beam"]), - %% Must have at least two files here, or there will could be + %% Must have at least two files here, or there will be %% a grammatical error in the output of the io:format/2 call below. ;-) ?line [_,_|_] = Fs = filelib:wildcard(Wc), ?line io:format("~p files\n", [length(Fs)]), @@ -356,6 +356,36 @@ illegal_instruction(Config) when is_list(Config) -> {{'_',y,0},{[],0,illegal_instruction}}] = Errors, ok. +%% The beam_validator used to assume that a GC guard BIF could +%% do a garbage collection even if it failed. That assumption +%% is not correct, and will cause the beam_validator to reject +%% valid programs such as this test case. +%% +%% (Thanks to Kiran Khaladkar.) +%% +failing_gc_guard_bif(Config) when is_list(Config) -> + ?line ok = process_request(lists:seq(1, 36)), + ?line error = process_request([]), + ?line error = process_request(not_a_list), + ok. + +process_request(ConfId) -> + case process_request_foo(ConfId) of + false -> + if + length(ConfId) == 36 -> + Response = ok; + true -> + Response = error + end + end, + process_request_bar(self(), [Response]). + +process_request_foo(_) -> + false. + +process_request_bar(Pid, [Response]) when is_pid(Pid) -> + Response. %%%------------------------------------------------------------------------- -- cgit v1.2.3