diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2011-12-29 15:28:32 +0100 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2012-01-11 08:39:56 +0100 |
commit | 68651be298a997a22224f53445688a74dc2fab7d (patch) | |
tree | c62acf8de66888109bcc09151ddefaa56fe7ec90 /lib/compiler/src | |
parent | 85f789f22ce07112be08354417b4179ee23427c7 (diff) | |
download | otp-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.erl | 24 |
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; |