aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_ssa_type.erl
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-06-26 13:26:05 +0200
committerJohn Högberg <[email protected]>2019-07-05 11:33:38 +0200
commit1e4e506b5c3af02632da29b0802e913121403bf4 (patch)
treecdbde9f73e81fb9130edd8ff81253092bd4ac402 /lib/compiler/src/beam_ssa_type.erl
parent950ce53fc5e4c80d10c78d0cf1fad88745b633eb (diff)
downloadotp-1e4e506b5c3af02632da29b0802e913121403bf4.tar.gz
otp-1e4e506b5c3af02632da29b0802e913121403bf4.tar.bz2
otp-1e4e506b5c3af02632da29b0802e913121403bf4.zip
beam_ssa_type: Fix type inference on BIFs without a success check
Diffstat (limited to 'lib/compiler/src/beam_ssa_type.erl')
-rw-r--r--lib/compiler/src/beam_ssa_type.erl29
1 files changed, 15 insertions, 14 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 79c67e5705..d88f43cb5c 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -1328,22 +1328,19 @@ infer_eq_lit(_, _) -> [].
infer_type(succeeded, [#b_var{}=Src], Ts, Ds) ->
#b_set{op=Op,args=Args} = maps:get(Src, Ds),
- infer_type(Op, Args, Ts, Ds);
-infer_type(bs_start_match, [#b_var{}=Bin], _Ts, _Ds) ->
- T = {Bin,#t_bitstring{}},
- {[T], [T]};
-infer_type(is_nonempty_list, [#b_var{}=Src], _Ts, _Ds) ->
- T = {Src,cons},
- {[T], [T]};
+ infer_success_type(Op, Args, Ts, Ds);
+
+%% Type tests are handled separately from other BIFs as we're inferring types
+%% based on their result, so we know that subtraction is safe even if we're
+%% not branching on 'succeeded'.
infer_type(is_tagged_tuple, [#b_var{}=Src,#b_literal{val=Size},
#b_literal{}=Tag], _Ts, _Ds) ->
Es = beam_types:set_element_type(1, get_type(Tag, #{}), #{}),
T = {Src,#t_tuple{exact=true,size=Size,elements=Es}},
{[T], [T]};
-
-%% Type tests are handled separately from other BIFs as we're inferring types
-%% based on their result rather than whether they succeeded, so we know that
-%% subtraction is always safe.
+infer_type(is_nonempty_list, [#b_var{}=Src], _Ts, _Ds) ->
+ T = {Src,cons},
+ {[T], [T]};
infer_type({bif,is_atom}, [Arg], _Ts, _Ds) ->
T = {Arg, #t_atom{}},
{[T], [T]};
@@ -1374,8 +1371,10 @@ infer_type({bif,is_number}, [Arg], _Ts, _Ds) ->
infer_type({bif,is_tuple}, [Arg], _Ts, _Ds) ->
T = {Arg, #t_tuple{}},
{[T], [T]};
+infer_type(_Op, _Args, _Ts, _Ds) ->
+ {[], []}.
-infer_type({bif,Op}, Args, Ts, _Ds) ->
+infer_success_type({bif,Op}, Args, Ts, _Ds) ->
ArgTypes = get_types(Args, Ts),
{_, PosTypes0, CanSubtract} = beam_call_types:types(erlang, Op, ArgTypes),
@@ -1385,8 +1384,10 @@ infer_type({bif,Op}, Args, Ts, _Ds) ->
true -> {PosTypes, PosTypes};
false -> {PosTypes, []}
end;
-
-infer_type(_Op, _Args, _Ts, _Ds) ->
+infer_success_type(bs_start_match, [#b_var{}=Bin], _Ts, _Ds) ->
+ T = {Bin,#t_bitstring{}},
+ {[T], [T]};
+infer_success_type(_Op, _Args, _Ts, _Ds) ->
{[], []}.
join_types(Ts0, Ts1) ->