aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/bs_match_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-06-07 14:27:15 +0200
committerBjörn Gustavsson <[email protected]>2017-06-07 16:32:35 +0200
commit09112806c15a81be86730503af36e304ac11d1ed (patch)
tree8f66b637b02762737f4e91bd7077428c736fed0e /lib/compiler/test/bs_match_SUITE.erl
parent1ee59088c52ff18e3917d7f453a5947d0fe1cadd (diff)
downloadotp-09112806c15a81be86730503af36e304ac11d1ed.tar.gz
otp-09112806c15a81be86730503af36e304ac11d1ed.tar.bz2
otp-09112806c15a81be86730503af36e304ac11d1ed.zip
Fix unsafe bit syntax matching optimization
As part of sys_core_fold, variables involved in bit syntax matching would be annotated when it would be safe for a later pass to do the delayed sub-binary creation optimization. An implicit assumption regarding the annotation was that the code must not be further optimized. That assumption was broken in 05130e48555891, which introduced a fixpoint iteration (applying the optimizations until there were no more changes). That means that a variable could be annotated as safe for reusing the match context in one iteration, but a later iteration could rewrite the code in a way that would make the optimization unsafe. One way to fix this would be to clear all reuse_for_context annotations before each iteration. But that would be wasteful. Instead I chose to fix the problem by moving out the annotation code to a separate pass (sys_core_bsm) that is run later after all major optimizations of Core Erlang has been done.
Diffstat (limited to 'lib/compiler/test/bs_match_SUITE.erl')
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl19
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 89f851ac3b..106d8eb45a 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -39,7 +39,7 @@
match_string_opt/1,select_on_integer/1,
map_and_binary/1,unsafe_branch_caching/1,
bad_literals/1,good_literals/1,constant_propagation/1,
- parse_xml/1]).
+ parse_xml/1,get_payload/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -70,7 +70,8 @@ groups() ->
no_partition,calling_a_binary,binary_in_map,
match_string_opt,select_on_integer,
map_and_binary,unsafe_branch_caching,
- bad_literals,good_literals,constant_propagation,parse_xml]}].
+ bad_literals,good_literals,constant_propagation,parse_xml,
+ get_payload]}].
init_per_suite(Config) ->
@@ -1508,6 +1509,20 @@ do_parse_xml(<<"<?xml"/utf8,Rest/binary>> = Bytes) ->
is_next_char_whitespace(<<C/utf8,_/binary>>) ->
C =:= $\s.
+-record(ext_header,
+ {this_hdr = 17,
+ ext_hdr_opts}).
+
+get_payload(Config) ->
+ <<3445:48>> = do_get_payload(#ext_header{ext_hdr_opts = <<3445:48>>}),
+ {'EXIT',_} = (catch do_get_payload(#ext_header{})),
+ ok.
+
+do_get_payload(ExtHdr) ->
+ _ = ExtHdr#ext_header.this_hdr,
+ ExtHdrOptions = ExtHdr#ext_header.ext_hdr_opts,
+ <<_:13,_:35>> = ExtHdr#ext_header.ext_hdr_opts,
+ ExtHdrOptions.
check(F, R) ->
R = F().