summaryrefslogtreecommitdiff
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2022-01-30 08:15:36 +0100
committerBjörn Gustavsson <bjorn@erlang.org>2022-01-31 14:15:27 +0100
commita94a627208c12a9a382b5fc2fc2a881ee150ffe2 (patch)
treeda00dd698930b47ee76504291a5b8f1c41f8c4c4 /lib/compiler/src/beam_validator.erl
parente818258f84fbecf232797df5d71ee46e23a43391 (diff)
downloaderlang-a94a627208c12a9a382b5fc2fc2a881ee150ffe2.tar.gz
beam_ssa_type: Infer the type for a tuple used as a lookup table
Find the type of a call to `erlang/2` where a literal tuple is used as a lookup table. Here is a truncated example from the `base64` module: element(X+1, {$A, $B, $C, $D, $E, $F, ...}) The type will be the join of the types of the elements.
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r--lib/compiler/src/beam_validator.erl23
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index adbddc7059..63b2dc9e07 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -3055,7 +3055,28 @@ assert_not_fragile(Lit, #vst{}) ->
bif_types(Op, Ss, Vst) ->
Args = [normalize(get_term_type(Arg, Vst)) || Arg <- Ss],
- beam_call_types:types(erlang, Op, Args).
+ case {Op,Ss} of
+ {element,[_,{literal,Tuple}]} when tuple_size(Tuple) > 0 ->
+ case beam_call_types:types(erlang, Op, Args) of
+ {any,ArgTypes,Safe} ->
+ RetType = join_tuple_elements(Tuple),
+ {RetType,ArgTypes,Safe};
+ Other ->
+ Other
+ end;
+ {_,_} ->
+ beam_call_types:types(erlang, Op, Args)
+ end.
+
+join_tuple_elements(Tuple) ->
+ join_tuple_elements(tuple_size(Tuple), Tuple, none).
+
+join_tuple_elements(0, _Tuple, Type) ->
+ Type;
+join_tuple_elements(I, Tuple, Type0) ->
+ Type1 = beam_types:make_type_from_value(element(I, Tuple)),
+ Type = beam_types:join(Type0, Type1),
+ join_tuple_elements(I - 1, Tuple, Type).
call_types({extfunc,M,F,A}, A, Vst) ->
Args = get_call_args(A, Vst),