diff options
author | Björn Gustavsson <[email protected]> | 2010-09-22 11:09:57 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-09-22 14:48:22 +0200 |
commit | 5daa0013177545446b26cdba0dbd167f0e040d63 (patch) | |
tree | 65a9ba5e7ea9291dc3202ef0830de261a64fb799 /lib/compiler/src | |
parent | 3142041ade649cfb783b4c1a52ee67cd2d2212f9 (diff) | |
download | otp-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.erl | 10 |
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) -> |