aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2011-12-29 15:28:32 +0100
committerBjörn Gustavsson <bjorn@erlang.org>2012-01-11 08:39:56 +0100
commit68651be298a997a22224f53445688a74dc2fab7d (patch)
treec62acf8de66888109bcc09151ddefaa56fe7ec90 /lib/compiler/src
parent85f789f22ce07112be08354417b4179ee23427c7 (diff)
downloadotp-68651be298a997a22224f53445688a74dc2fab7d.tar.gz
otp-68651be298a997a22224f53445688a74dc2fab7d.tar.bz2
otp-68651be298a997a22224f53445688a74dc2fab7d.zip
sys_core_fold: Fix opt_guard_try/1
opt_guard_try/1 assumed that it was only operating on guards, and implicitly assumed that any function call was to BIFs without any side effects.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/sys_core_fold.erl24
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 620b4e8847..c92ee86e07 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -150,14 +150,26 @@ guard(Expr, Sub) ->
opt_guard_try(#c_seq{arg=Arg,body=Body0}=Seq) ->
Body = opt_guard_try(Body0),
case {Arg,Body} of
- {#c_call{},#c_literal{val=false}} ->
- %% We have sequence consisting of a call (evaluted
- %% for a possible exception only), followed by 'false'.
- %% Since the sequence is inside a try block that will
+ {#c_call{module=#c_literal{val=Mod},
+ name=#c_literal{val=Name},
+ args=Args},#c_literal{val=false}} ->
+ %% We have sequence consisting of a call (evaluated
+ %% for a possible exception and/or side effect only),
+ %% followed by 'false'.
+ %% Since the sequence is inside a try block that will
%% default to 'false' if any exception occurs, not
%% evalutating the call will not change the behaviour
- %% of the guard.
- Body;
+ %% provided that the call has no side effects.
+ case erl_bifs:is_pure(Mod, Name, length(Args)) of
+ false ->
+ %% Not a pure BIF (meaning that this is not
+ %% a guard and that we must keep the call).
+ Seq#c_seq{body=Body};
+ true ->
+ %% The BIF has no side effects, so it can
+ %% be safely removed.
+ Body
+ end;
{_,_} ->
Seq#c_seq{body=Body}
end;