From 562cf135b9518985d172d291665eb32f891032fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 20 Aug 2012 10:11:38 +0200 Subject: v3_kernel: Fix match code for matched out segment size in multiple clauses When matched variable is used as a size field in multiple clauses, as in: foo(<>) -> A; foo(<>) -> {A,B}. the match tree would branch out before the segment that used the matched-out variable (in this example, the tree would branch out before the matching of A:L). That happens because the pattern matching compilator did not take variable substitutions into account when grouping clauses that match the same value. That is, the generated code would work similarly to this code: foo(<>) -> case T of <> -> A; _ -> case T of <> -> %% A matched out again! {A,B} end end. We would like the matching to work more like: foo(<>) -> case T of <<>> -> A; <> -> {A,B} end. Fix the problem by taking the substitutions into account when grouping clauses that match out the same value. --- lib/compiler/src/v3_kernel.erl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/compiler/src') diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index b69ad416db..8ef71e1346 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -1381,7 +1381,7 @@ clause_arg(#iclause{pats=[Arg|_]}) -> Arg. clause_con(C) -> arg_con(clause_arg(C)). -clause_val(C) -> arg_val(clause_arg(C)). +clause_val(C) -> arg_val(clause_arg(C), C). is_var_clause(C) -> clause_con(C) =:= k_var. @@ -1412,7 +1412,7 @@ arg_con(Arg) -> #k_var{} -> k_var end. -arg_val(Arg) -> +arg_val(Arg, C) -> case arg_arg(Arg) of #k_literal{val=Lit} -> Lit; #k_int{val=I} -> I; @@ -1420,7 +1420,13 @@ arg_val(Arg) -> #k_atom{val=A} -> A; #k_tuple{es=Es} -> length(Es); #k_bin_seg{size=S,unit=U,type=T,flags=Fs} -> - {set_kanno(S, []),U,T,Fs} + case S of + #k_var{name=V} -> + #iclause{isub=Isub} = C, + {#k_var{name=get_vsub(V, Isub)},U,T,Fs}; + _ -> + {set_kanno(S, []),U,T,Fs} + end end. %% ubody_used_vars(Expr, State) -> [UsedVar] -- cgit v1.2.3