diff options
| author | John Högberg <[email protected]> | 2019-05-28 17:09:42 +0200 | 
|---|---|---|
| committer | John Högberg <[email protected]> | 2019-06-11 15:47:38 +0200 | 
| commit | 2821afd35f0c7223bca45e6031ea210b4fcaa2a5 (patch) | |
| tree | ea177043de0351841a3458a5941b7e9412986f04 /lib/compiler/src | |
| parent | c02fc618f98c9fb97b15aae97e11fa1c23e250fc (diff) | |
| download | otp-2821afd35f0c7223bca45e6031ea210b4fcaa2a5.tar.gz otp-2821afd35f0c7223bca45e6031ea210b4fcaa2a5.tar.bz2 otp-2821afd35f0c7223bca45e6031ea210b4fcaa2a5.zip | |
beam_ssa_type: Fix meet/join inconsistency
meet/2 and join/2 were not entirely consistent with each other,
and it was possible to meet integers that didn't overlap,
producing a nonsense result.
None of these can cause issues in the OTP 22 track as far as we can
tell, so a patch doesn't feel necessary at this time.
Diffstat (limited to 'lib/compiler/src')
| -rw-r--r-- | lib/compiler/src/beam_ssa_type.erl | 14 | 
1 files changed, 9 insertions, 5 deletions
| diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl index c163d544ce..f8fefa8936 100644 --- a/lib/compiler/src/beam_ssa_type.erl +++ b/lib/compiler/src/beam_ssa_type.erl @@ -1860,6 +1860,9 @@ join(#t_atom{elements=[_|_]}, #t_atom{elements=any}=T) -> T;  join({binary,U1}, {binary,U2}) ->      {binary,gcd(U1, U2)};  join(#t_fun{}, #t_fun{}) -> #t_fun{}; +join(#t_integer{elements={MinA,MaxA}}, +     #t_integer{elements={MinB,MaxB}}) -> +    #t_integer{elements={min(MinA,MinB),max(MaxA,MaxB)}};  join(#t_integer{}, #t_integer{}) -> t_integer();  join(list, cons) -> list;  join(cons, list) -> list; @@ -1985,9 +1988,10 @@ meet(#t_integer{elements={_,_}}=T, #t_integer{elements=any}) ->      T;  meet(#t_integer{elements=any}, #t_integer{elements={_,_}}=T) ->      T; -meet(#t_integer{elements={Min1,Max1}}, -     #t_integer{elements={Min2,Max2}}) -> -    #t_integer{elements={max(Min1, Min2),min(Max1, Max2)}}; +meet(#t_integer{elements={MinA,MaxA}}, #t_integer{elements={MinB,MaxB}}) +  when MinA >= MinB, MaxA =< MaxB; +       MinB >= MinA, MaxB =< MaxA -> +    #t_integer{elements={max(MinA, MinB),min(MaxA, MaxB)}};  meet(#t_integer{}=T, number) -> T;  meet(float=T, number) -> T;  meet(number, #t_integer{}=T) -> T; @@ -1999,7 +2003,7 @@ meet(nil, list) -> nil;  meet(#t_tuple{}=T1, #t_tuple{}=T2) ->      meet_tuples(T1, T2);  meet({binary,U1}, {binary,U2}) -> -    {binary,max(U1, U2)}; +    {binary, U1 * U2 div gcd(U1, U2)};  meet(any, T) ->      verified_type(T);  meet(T, any) -> @@ -2073,7 +2077,7 @@ verified_type({binary,U}=T) when is_integer(U) -> T;  verified_type(#t_fun{arity=Arity}=T) when Arity =:= any; is_integer(Arity) -> T;  verified_type(#t_integer{elements=any}=T) -> T;  verified_type(#t_integer{elements={Min,Max}}=T) -  when is_integer(Min), is_integer(Max) -> T; +  when is_integer(Min), is_integer(Max), Min =< Max -> T;  verified_type(list=T) -> T;  verified_type(map=T) -> T;  verified_type(nil=T) -> T; | 
