diff options
author | Björn Gustavsson <[email protected]> | 2009-12-10 21:18:39 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2009-12-10 21:43:08 +0100 |
commit | af198c489a7ab431fd1e2b52d16e8e13525915f7 (patch) | |
tree | db869146ecc862955dfb306292a42c8ae4b8c507 /lib/compiler/src | |
parent | 9855ed863b58f7325f39b00c60813198ec41f528 (diff) | |
download | otp-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.erl | 15 |
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. |