aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-09-22 11:09:57 +0200
committerBjörn Gustavsson <[email protected]>2010-09-22 14:48:22 +0200
commit5daa0013177545446b26cdba0dbd167f0e040d63 (patch)
tree65a9ba5e7ea9291dc3202ef0830de261a64fb799 /lib/compiler/src
parent3142041ade649cfb783b4c1a52ee67cd2d2212f9 (diff)
downloadotp-5daa0013177545446b26cdba0dbd167f0e040d63.tar.gz
otp-5daa0013177545446b26cdba0dbd167f0e040d63.tar.bz2
otp-5daa0013177545446b26cdba0dbd167f0e040d63.zip
Don't generate multiple tail segments in binary matching
In binary matching, there must only be one "tail segment" (i.e. a size-less segment of type binary) and it must be last. Thus, the compiler will reject the following function definition: foo(<<A/bits,B/bits>>) -> ok. But code such as the following: [42 || <<_:8/integer, _/bits>> <= Bits] will internally (in the Core Erlang format) be translated to a binary matching pattern containing two tail segments. The compiler happens to generate correct code anyway (later passes will get rid of the redundant tail segment), but it is ugly and will confuse tools such as Dialyzer. Change the transformation of binary generators (in both list and binary comprehensions) not to generate add a tail segment if there already is one.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/v3_core.erl10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 3f33dbca52..2da24b2908 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1118,6 +1118,16 @@ bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) ->
append_tail_segment(Segs, St) ->
app_tail_seg(Segs, St, []).
+app_tail_seg([#c_bitstr{val=Var0,size=#c_literal{val=all}}=Seg0]=L,
+ St0, Acc) ->
+ case Var0 of
+ #c_var{name='_'} ->
+ {Var,St} = new_var(St0),
+ Seg = Seg0#c_bitstr{val=Var},
+ {reverse(Acc, [Seg]),Var,St};
+ #c_var{} ->
+ {reverse(Acc, L),Var0,St0}
+ end;
app_tail_seg([H|T], St, Acc) ->
app_tail_seg(T, St, [H|Acc]);
app_tail_seg([], St0, Acc) ->