From 78a6f7fc67991e61d6f62c4056e11c22b7b1387b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 24 Sep 2018 12:39:25 +0200 Subject: beam_validator: Disallow literal arguments for certain instructions Disallow a literal map source for get_map_elements. There is currently runtime support for get_map with a literal map source, but by forbidding it in OTP 22, the runtime support could be removed in a future release (perhaps OTP 24). Also verify that the source arguments for get_list, get_hd, get_tl, and get_tuple_element are not literals. Literals are not supported for those instructions in the runtime system; verifying it in beam_validator is a convenience so that this kind of bug will be detected already during compilation. --- lib/compiler/src/beam_validator.erl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index e76b097500..68544d97ee 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -459,16 +459,20 @@ valfun_1({try_case,Reg}, #vst{current=#st{ct=[Fail|Fails]}}=Vst0) -> error({bad_type,Type}) end; valfun_1({get_list,Src,D1,D2}, Vst0) -> + assert_not_literal(Src), assert_type(cons, Src, Vst0), Vst = set_type_reg(term, Src, D1, Vst0), set_type_reg(term, Src, D2, Vst); valfun_1({get_hd,Src,Dst}, Vst) -> + assert_not_literal(Src), assert_type(cons, Src, Vst), set_type_reg(term, Src, Dst, Vst); valfun_1({get_tl,Src,Dst}, Vst) -> + assert_not_literal(Src), assert_type(cons, Src, Vst), set_type_reg(term, Src, Dst, Vst); valfun_1({get_tuple_element,Src,I,Dst}, Vst) -> + assert_not_literal(Src), assert_type({tuple_element,I+1}, Src, Vst), set_type_reg(term, Src, Dst, Vst); valfun_1({jump,{f,Lbl}}, Vst) -> @@ -875,6 +879,7 @@ valfun_4(_, _) -> error(unknown_instruction). verify_get_map(Fail, Src, List, Vst0) -> + assert_not_literal(Src), %OTP 22. assert_type(map, Src, Vst0), Vst1 = foldl(fun(D, Vsti) -> case is_reg_defined(D,Vsti) of @@ -1427,6 +1432,10 @@ assert_term(Src, Vst) -> get_term_type(Src, Vst), ok. +assert_not_literal({x,_}) -> ok; +assert_not_literal({y,_}) -> ok; +assert_not_literal(Literal) -> error({literal_not_allowed,Literal}). + %% The possible types. %% %% First non-term types: -- cgit v1.2.3