aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2018-08-31 07:58:46 +0200
committerGitHub <[email protected]>2018-08-31 07:58:46 +0200
commitcd9ba7cff2ff8fdd67094a576cd4f1b92dbc6c8d (patch)
treef8453511aa68e9a2fe6dcf0c6b07ecbbf57662ad /lib/compiler
parent572fed38106ccd490352bceb3fcecb34f33f9e18 (diff)
parentfd9b5ae4193fbab66093c88728c0dbeaa3b57312 (diff)
downloadotp-cd9ba7cff2ff8fdd67094a576cd4f1b92dbc6c8d.tar.gz
otp-cd9ba7cff2ff8fdd67094a576cd4f1b92dbc6c8d.tar.bz2
otp-cd9ba7cff2ff8fdd67094a576cd4f1b92dbc6c8d.zip
Merge pull request #1944 from uabboli/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 5aaf5bfd51..45e0ed5088 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -329,14 +329,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},
@@ -2055,6 +2057,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 ->