@@ -2292,12 +2292,15 @@ infer_types_1(#value{op={bif,is_integer},args=[Src,
22922292 {integer , Min },
22932293 {integer , Max }]}, Val , Op , Vst ) ->
22942294 infer_type_test_bif (beam_types :make_integer (Min , Max ), Src , Val , Op , Vst );
2295- infer_types_1 (# value {op = {bif ,is_integer },args = [Src , _ , _ ]}, Val , Op , Vst ) ->
2296- % % Unknown bounds; we know it's an integer when 'true', but cannot draw
2297- % % any conclusions when 'false'.
2295+ infer_types_1 (# value {op = {bif ,is_integer },args = [Src ,Min0 ,Max0 ]}, Val , Op , Vst ) ->
2296+ % % If there is at least one unknown bound, we cannot subtract
2297+ % % when 'false'.
2298+ {Min ,_ } = infer_integer_get_range (Min0 , Vst ),
2299+ {_ ,Max } = infer_integer_get_range (Max0 , Vst ),
2300+ Type = make_integer ({Min , Max }),
22982301 case Val of
22992302 {atom , Bool } when Op =:= eq_exact , Bool ; Op =:= ne_exact , not Bool ->
2300- update_type (fun meet /2 , # t_integer {} , Src , Vst );
2303+ update_type (fun meet /2 , Type , Src , Vst );
23012304 _ ->
23022305 Vst
23032306 end ;
@@ -2367,6 +2370,25 @@ invert_relop('=<') -> '>';
23672370invert_relop ('>=' ) -> '<' ;
23682371invert_relop ('>' ) -> '=<' .
23692372
2373+ infer_integer_get_range (Arg , Vst ) ->
2374+ case get_term_type (Arg , Vst ) of
2375+ # t_integer {elements = {_ ,_ }= R } ->
2376+ R ;
2377+ # t_number {elements = {Min ,Max }= R }
2378+ when is_integer (Min ), is_integer (Max ) -> R ;
2379+ _ ->
2380+ {'-inf' ,'+inf' }
2381+ end .
2382+
2383+ make_integer ({'-inf' ,'+inf' }) ->
2384+ # t_integer {};
2385+ make_integer ({'-inf' ,_ }= R ) ->
2386+ # t_integer {elements = R };
2387+ make_integer ({Min ,Max }= R ) when is_integer (Min ), Min =< Max ->
2388+ # t_integer {elements = R };
2389+ make_integer (_ ) ->
2390+ # t_integer {}.
2391+
23702392% %%
23712393% %% Keeping track of types.
23722394% %%
0 commit comments