aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2018-08-31 08:08:46 +0200
committerHans Bolinder <[email protected]>2018-08-31 08:08:46 +0200
commit583b7add1d66616e61c332ded0658c684c39c8c6 (patch)
treebdd3882e8b98eacf3d5638050522ad013bc5c184 /lib/compiler
parent96aa684ffcae8f70898aa6b924fa82804d537488 (diff)
parentfd9b5ae4193fbab66093c88728c0dbeaa3b57312 (diff)
downloadotp-583b7add1d66616e61c332ded0658c684c39c8c6.tar.gz
otp-583b7add1d66616e61c332ded0658c684c39c8c6.tar.bz2
otp-583b7add1d66616e61c332ded0658c684c39c8c6.zip
Merge branch 'hasse/dialyzer/improve_guards/OTP-15268/ERL-680' into maint
* hasse/dialyzer/improve_guards/OTP-15268/ERL-680: dialyzer: Improve handling of complex guards
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/v3_core.erl19
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 3b746ab5bf..c9517c3e51 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -328,14 +328,16 @@ gexpr({protect,Line,Arg}, Bools0, St0) ->
Anno = lineno_anno(Line, St),
{#iprotect{anno=#a{anno=Anno},body=Eps++[E]},[],Bools0,St}
end;
-gexpr({op,L,'andalso',E1,E2}, Bools, St0) ->
+gexpr({op,_,'andalso',_,_}=E0, Bools, St0) ->
+ {op,L,'andalso',E1,E2} = right_assoc(E0, 'andalso', St0),
Anno = lineno_anno(L, St0),
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
False = {atom,L,false},
E = make_bool_switch_guard(L, E1, V, E2, False),
gexpr(E, Bools, St);
-gexpr({op,L,'orelse',E1,E2}, Bools, St0) ->
+gexpr({op,_,'orelse',_,_}=E0, Bools, St0) ->
+ {op,L,'orelse',E1,E2} = right_assoc(E0, 'orelse', St0),
Anno = lineno_anno(L, St0),
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
@@ -2054,6 +2056,19 @@ fail_clause(Pats, Anno, Arg) ->
body=[#iprimop{anno=#a{anno=Anno},name=#c_literal{val=match_fail},
args=[Arg]}]}.
+%% Optimization for Dialyzer.
+right_assoc(E, Op, St) ->
+ case member(dialyzer, St#core.opts) of
+ true ->
+ right_assoc2(E, Op);
+ false ->
+ E
+ end.
+
+right_assoc2({op,L1,Op,{op,L2,Op,E1,E2},E3}, Op) ->
+ right_assoc2({op,L2,Op,E1,{op,L1,Op,E2,E3}}, Op);
+right_assoc2(E, _Op) -> E.
+
annotate_tuple(A, Es, St) ->
case member(dialyzer, St#core.opts) of
true ->