From f7fe4573880ce94d794af266d0f37459b7a86709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 24 May 2019 16:08:55 +0200 Subject: Fix compiler crash in beam_except The compiler would crash in `beam_except` while compiling this function: bar(Req) -> ok = case Req of "POST" -> {error, <<"BAD METHOD ", Req/binary>>, Req}; _ -> ok end. https://bugs.erlang.org/browse/ERL-954 --- lib/compiler/src/beam_except.erl | 7 +++++-- lib/compiler/test/beam_except_SUITE.erl | 20 ++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/compiler/src/beam_except.erl b/lib/compiler/src/beam_except.erl index 28c89782c9..2305502800 100644 --- a/lib/compiler/src/beam_except.erl +++ b/lib/compiler/src/beam_except.erl @@ -140,8 +140,11 @@ fix_block_1([{set,[],[],{alloc,Live,{F1,F2,Needed0,F3}}}|Is], Words) -> [{set,[],[],{alloc,Live,{F1,F2,Needed,F3}}}|Is] end; fix_block_1([I|Is], Words) -> - [I|fix_block_1(Is, Words)]. - + [I|fix_block_1(Is, Words)]; +fix_block_1([], _Words) -> + %% Rare. The heap allocation was probably done by a binary + %% construction instruction. + []. dig_out_fc(Arity, Is0) -> Regs0 = maps:from_list([{{x,X},{arg,X}} || X <- seq(0, Arity-1)]), diff --git a/lib/compiler/test/beam_except_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl index 8e3b373d29..67947dc292 100644 --- a/lib/compiler/test/beam_except_SUITE.erl +++ b/lib/compiler/test/beam_except_SUITE.erl @@ -21,7 +21,8 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - multiple_allocs/1,bs_get_tail/1,coverage/1]). + multiple_allocs/1,bs_get_tail/1,coverage/1, + binary_construction_allocation/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -32,7 +33,8 @@ groups() -> [{p,[parallel], [multiple_allocs, bs_get_tail, - coverage]}]. + coverage, + binary_construction_allocation]}]. init_per_suite(Config) -> test_lib:recompile(?MODULE), @@ -118,6 +120,20 @@ coverage(_) -> fake_function_clause(A) -> error(function_clause, [A,42.0]). + +binary_construction_allocation(_Config) -> + ok = do_binary_construction_allocation("PUT"), + ok. + +do_binary_construction_allocation(Req) -> + %% Allocation for building the error term was done by the + %% bs_init2 instruction. beam_except crashed because it expected + %% an explicit allocation instruction. + ok = case Req of + "POST" -> {error, <<"BAD METHOD ", Req/binary>>, Req}; + _ -> ok + end. + id(I) -> I. -file("fake.erl", 1). -- cgit v1.2.3