aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/receive_SUITE.erl
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-02-27 10:44:46 +0100
committerJohn Högberg <[email protected]>2019-02-27 14:59:40 +0100
commit36b7654dc152f6b3343afb664a7b260dcc06c799 (patch)
tree449cafc0ff3e240d16b6112c5c2c566c5bc2e7c6 /lib/compiler/test/receive_SUITE.erl
parent4bad7cfb05311ad1fbd916991e83e36018e0ebf5 (diff)
downloadotp-36b7654dc152f6b3343afb664a7b260dcc06c799.tar.gz
otp-36b7654dc152f6b3343afb664a7b260dcc06c799.tar.bz2
otp-36b7654dc152f6b3343afb664a7b260dcc06c799.zip
beam_validator: Don't explode when building terms in receive
Building terms with fragile contents is okay because the GC is disabled during loop_rec, and the resulting term won't be reachable from the root set afterwards. ERL-862
Diffstat (limited to 'lib/compiler/test/receive_SUITE.erl')
-rw-r--r--lib/compiler/test/receive_SUITE.erl30
1 files changed, 28 insertions, 2 deletions
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 12108445f0..0038eb1a4b 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -25,7 +25,8 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
export/1,recv/1,coverage/1,otp_7980/1,ref_opt/1,
- wait/1,recv_in_try/1,double_recv/1,receive_var_zero/1]).
+ wait/1,recv_in_try/1,double_recv/1,receive_var_zero/1,
+ match_built_terms/1]).
-include_lib("common_test/include/ct.hrl").
@@ -45,7 +46,8 @@ all() ->
groups() ->
[{p,test_lib:parallel(),
[recv,coverage,otp_7980,ref_opt,export,wait,
- recv_in_try,double_recv,receive_var_zero]}].
+ recv_in_try,double_recv,receive_var_zero,
+ match_built_terms]}].
init_per_suite(Config) ->
@@ -400,5 +402,29 @@ receive_var_zero(Config) when is_list(Config) ->
zero() -> 0.
+%% ERL-862; the validator would explode when a term was constructed in a
+%% receive guard.
+
+-define(MATCH_BUILT_TERM(Ref, Expr),
+ (fun() ->
+ Ref = make_ref(),
+ A = id($a),
+ B = id($b),
+ Built = id(Expr),
+ self() ! {Ref, A, B},
+ receive
+ {Ref, A, B} when Expr =:= Built ->
+ ok
+ after 5000 ->
+ ct:fail("Failed to match message with term built in "
+ "receive guard.")
+ end
+ end)()).
+
+match_built_terms(Config) when is_list(Config) ->
+ ?MATCH_BUILT_TERM(Ref, [A, B]),
+ ?MATCH_BUILT_TERM(Ref, {A, B}),
+ ?MATCH_BUILT_TERM(Ref, <<A, B>>),
+ ?MATCH_BUILT_TERM(Ref, #{ 1 => A, 2 => B}).
id(I) -> I.