aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-03-04 12:34:51 +0100
committerJohn Högberg <[email protected]>2019-03-04 14:09:43 +0100
commit6d6a82c78e6d3064e32e6686b4ac32d48cefed95 (patch)
tree555f5107fc67b9fc699e193c2733a4583cc8098e /lib/compiler/src
parent5961262c1f479be84903cf078d7679c2bc65d973 (diff)
downloadotp-6d6a82c78e6d3064e32e6686b4ac32d48cefed95.tar.gz
otp-6d6a82c78e6d3064e32e6686b4ac32d48cefed95.tar.bz2
otp-6d6a82c78e6d3064e32e6686b4ac32d48cefed95.zip
beam_validator: Fix element/2 BIF handling
The element type can not be extracted before the tuple type has been updated.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_validator.erl12
1 files changed, 7 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 164007548c..472bb1b22e 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -683,12 +683,15 @@ valfun_4({make_fun2,_,_,_,Live}, Vst) ->
call(make_fun, Live, Vst);
%% Other BIFs
valfun_4({bif,element,{f,Fail},[Pos,Tuple],Dst}, Vst0) ->
+ Vst1 = branch_state(Fail, Vst0),
+
PosType = get_term_type(Pos, Vst0),
- ElementType = get_element_type(PosType, Tuple, Vst0),
InferredType = {tuple,[get_tuple_size(PosType)],#{}},
- Vst1 = branch_state(Fail, Vst0),
+
Vst2 = update_type(fun meet/2, InferredType, Tuple, Vst1),
Vst = update_type(fun meet/2, {integer,[]}, Pos, Vst2),
+
+ ElementType = get_element_type(PosType, Tuple, Vst),
extract_term(ElementType, {bif,element}, [Pos,Tuple], Dst, Vst);
valfun_4({bif,raise,{f,0},Src,_Dst}, Vst) ->
validate_src(Src, Vst),
@@ -2082,11 +2085,10 @@ assert_type(Needed, Actual) ->
get_element_type(Key, Src, Vst) ->
get_element_type_1(Key, get_term_type(Src, Vst)).
-get_element_type_1({integer,Index}=Key, {tuple,Sz,Es}) ->
+get_element_type_1({integer,_}=Key, {tuple,_Sz,Es}) ->
case Es of
#{ Key := Type } -> Type;
- #{} when Index =< Sz -> term;
- #{} -> none
+ #{} -> term
end;
get_element_type_1(_Index, _Type) ->
term.