aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-01-04 16:40:31 +0100
committerBjörn Gustavsson <[email protected]>2012-01-11 08:39:57 +0100
commit823f47c8cf3c7a4f32401cae5a2e47916d3593e4 (patch)
tree91a22170ccbb6c50d23e20f0ff35fafda8004bcf /lib/compiler
parent1955804aaf831f943941555ab6f46ee22e5a0dac (diff)
downloadotp-823f47c8cf3c7a4f32401cae5a2e47916d3593e4.tar.gz
otp-823f47c8cf3c7a4f32401cae5a2e47916d3593e4.tar.bz2
otp-823f47c8cf3c7a4f32401cae5a2e47916d3593e4.zip
v3_kernel: Handle sequences in guards
A guard with a sequence will cause a crash in v3_codegen. Currently, it seems that a sequence in a guard will never happen when compiling from Erlang code, but there are several reasons to fix this problem anyway: * There are other compilers that generate Core Erlang code. * Changes to sys_core_fold (perhaps additional optimizations) may cause sequences to be generated in guards. * A previously uncovered line in sys_core_fold:opt_guard_try/1 will now be covered.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/v3_kernel.erl7
-rw-r--r--lib/compiler/test/core_SUITE.erl5
-rw-r--r--lib/compiler/test/core_SUITE_data/seq_in_guard.core66
3 files changed, 73 insertions, 5 deletions
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 67e22a5662..8bbaf183c8 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -1537,10 +1537,11 @@ uguard_expr(#k_test{anno=A,op=Op,args=As}=Test, Rs, St) ->
Used = union(op_vars(Op), lit_list_vars(As)),
{Test#k_test{anno=#k{us=Used,ns=lit_list_vars(Rs),a=A}},
Used,St};
-uguard_expr(#k_bif{anno=A,op=Op,args=As}=Bif, Rs, St) ->
+uguard_expr(#k_bif{anno=A,op=Op,args=As}=Bif, Rs, St0) ->
Used = union(op_vars(Op), lit_list_vars(As)),
- {Bif#k_bif{anno=#k{us=Used,ns=lit_list_vars(Rs),a=A},ret=Rs},
- Used,St};
+ {Brs,St1} = bif_returns(Op, Rs, St0),
+ {Bif#k_bif{anno=#k{us=Used,ns=lit_list_vars(Brs),a=A},ret=Brs},
+ Used,St1};
uguard_expr(#ivalues{anno=A,args=As}, Rs, St) ->
Sets = foldr2(fun (V, Arg, Rhs) ->
#iset{anno=A,vars=[V],arg=Arg,body=Rhs}
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index 874e02803d..fd1539e7fd 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -22,7 +22,7 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
dehydrated_itracer/1,nested_tries/1,
- make_effect_seq/1,eval_is_boolean/1,
+ seq_in_guard/1,make_effect_seq/1,eval_is_boolean/1,
unsafe_case/1,nomatch_shadow/1,reversed_annos/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [dehydrated_itracer,nested_tries,make_effect_seq,
+ [dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos].
groups() ->
@@ -64,6 +64,7 @@ end_per_group(_GroupName, Config) ->
?comp(dehydrated_itracer).
?comp(nested_tries).
+?comp(seq_in_guard).
?comp(make_effect_seq).
?comp(eval_is_boolean).
?comp(unsafe_case).
diff --git a/lib/compiler/test/core_SUITE_data/seq_in_guard.core b/lib/compiler/test/core_SUITE_data/seq_in_guard.core
new file mode 100644
index 0000000000..44686a7187
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/seq_in_guard.core
@@ -0,0 +1,66 @@
+module 'seq_in_guard' ['seq_in_guard'/0,
+ 't'/1]
+ attributes []
+'seq_in_guard'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ let <_cor0> =
+ catch
+ %% Line 5
+ apply 't'/1
+ ({})
+ in %% Line 5
+ case _cor0 of
+ <{'EXIT',{'function_clause',_cor4}}> when 'true' ->
+ let <_cor2> =
+ catch
+ %% Line 6
+ apply 't'/1
+ ('atom')
+ in %% Line 6
+ case _cor2 of
+ <{'EXIT',{'function_clause',_cor5}}> when 'true' ->
+ %% Line 7
+ apply 't'/1
+ ({'a','b'})
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'seq_in_guard',0}}] )
+ -| ['compiler_generated'] )
+ end
+'t'/1 =
+ %% Line 9
+ fun (_cor0) ->
+ case _cor0 of
+ <X>
+ when try
+ do
+ call 'erlang':'element'
+ (2, X)
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ %% Line 10
+ 'ok'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'t',1}}] )
+ -| ['compiler_generated'] )
+ end
+end