aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2009-12-10 21:18:39 +0100
committerBjörn Gustavsson <[email protected]>2009-12-10 21:43:08 +0100
commitaf198c489a7ab431fd1e2b52d16e8e13525915f7 (patch)
treedb869146ecc862955dfb306292a42c8ae4b8c507 /lib/compiler/src
parent9855ed863b58f7325f39b00c60813198ec41f528 (diff)
downloadotp-af198c489a7ab431fd1e2b52d16e8e13525915f7.tar.gz
otp-af198c489a7ab431fd1e2b52d16e8e13525915f7.tar.bz2
otp-af198c489a7ab431fd1e2b52d16e8e13525915f7.zip
Fix crash in beam_bool
The following code crashes beam_bool: bad(XDo1, XDo2, Do3) -> Do1 = (XDo1 =/= []), Do2 = (XDo2 =/= []), if Do1 =:= true; Do1 =:= false, Do2 =:= false, Do3 =:= delete -> no end. (Reported by Simon Cornish; minimized by Kostis Sagonas.) For the moment fix the bug in the simplest and safest way possible (basically, instead of crashing just don't do the optimization). In a future major release (e.g. R14), the following improvements could be considered: * In beam_bool, it should be possible to move the Do1 and Do2 expressions to the pre-block and still optimize the expression in the 'if' statement. * In sys_core_fold, it should be possible to eliminate the try/catch around the guard expression in the 'if', because none of the guard tests can actually fail.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_bool.erl15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index d8c201a194..ffe5cdb501 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -123,6 +123,12 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
throw:mixed ->
failed;
+ %% There was a reference to a boolean expression
+ %% from inside a protected block (try/catch), to
+ %% a boolean expression outside.
+ throw:protected_barrier ->
+ failed;
+
%% The 'xor' operator was used. We currently don't
%% find it worthwile to translate 'xor' operators
%% (the code would be clumsy).
@@ -414,11 +420,10 @@ bopt_good_args([A|As], Regs) ->
bopt_good_args([], _) -> ok.
bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:get(X, Regs) of
- any -> ok;
- _Other ->
- %%io:format("not any: ~p: ~p\n", [X,_Other]),
- throw(mixed)
+ case gb_trees:lookup(X, Regs) of
+ {value,any} -> ok;
+ {value,_} -> throw(mixed);
+ none -> throw(protected_barrier)
end;
bopt_good_arg(_, _) -> ok.