diff options
author | John Högberg <john@erlang.org> | 2023-02-22 12:17:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-22 12:17:49 +0100 |
commit | ca77c52d2ed2a578648996b3178aaf4a21d44095 (patch) | |
tree | 5e2bd3fe9ef445fd08808283aaa12115ded014ef | |
parent | d318661ccb9f9ae775533551052ca05af2a3f7eb (diff) | |
parent | 28b1d8fe91763abfde7672f2d3d5e3beab98c445 (diff) | |
download | erlang-ca77c52d2ed2a578648996b3178aaf4a21d44095.tar.gz |
Merge pull request #6842 from jhogberg/john/compiler/infer-more-arithmetic
beam_call_types: Infer range of various arithmetic operations
-rw-r--r-- | lib/compiler/src/beam_call_types.erl | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl index 6226b6d088..8285425374 100644 --- a/lib/compiler/src/beam_call_types.erl +++ b/lib/compiler/src/beam_call_types.erl @@ -396,15 +396,18 @@ types(erlang, 'band', [_,_]=Args) -> types(erlang, 'bor', [_,_]=Args) -> sub_unsafe(beam_bounds_type('bor', #t_integer{}, Args), [#t_integer{}, #t_integer{}]); -types(erlang, 'bxor', [_,_]) -> - sub_unsafe(#t_integer{}, [#t_integer{}, #t_integer{}]); -types(erlang, 'bsl', [_,_]) -> - sub_unsafe(#t_integer{}, [#t_integer{}, #t_integer{}]); +types(erlang, 'bxor', [_,_]=Args) -> + sub_unsafe(beam_bounds_type('bxor', #t_integer{}, Args), + [#t_integer{}, #t_integer{}]); +types(erlang, 'bsl', [_,_]=Args) -> + sub_unsafe(beam_bounds_type('bsl', #t_integer{}, Args), + [#t_integer{}, #t_integer{}]); types(erlang, 'bsr', [_,_]=Args) -> sub_unsafe(beam_bounds_type('bsr', #t_integer{}, Args), [#t_integer{}, #t_integer{}]); -types(erlang, 'bnot', [_]) -> - sub_unsafe(#t_integer{}, [#t_integer{}]); +types(erlang, 'bnot', [_]=Args) -> + sub_unsafe(beam_bounds_type('bnot', #t_integer{}, Args), + [#t_integer{}]); %% Fixed-type arithmetic types(erlang, 'float', [_]) -> @@ -1081,6 +1084,17 @@ beam_bounds_type(Op, Type, [LHS, RHS]) -> #t_integer{elements=beam_bounds:bounds(Op, R1, R2)}; {number, R1, R2} -> #t_number{elements=beam_bounds:bounds(Op, R1, R2)} + end; +beam_bounds_type(Op, Type, [Arg]) -> + case beam_types:meet(Arg, Type) of + #t_float{elements=R} -> + #t_float{elements=beam_bounds:bounds(Op, R)}; + #t_integer{elements=R} -> + #t_integer{elements=beam_bounds:bounds(Op, R)}; + #t_number{elements=R} -> + #t_number{elements=beam_bounds:bounds(Op, R)}; + none -> + none end. get_range(LHS, RHS, Type) -> |