Skip to content

Commit 279f524

Browse files
committed
fix validator
1 parent c4b9509 commit 279f524

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

lib/compiler/src/beam_validator.erl

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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('=<') -> '>';
23672370
invert_relop('>=') -> '<';
23682371
invert_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
%%%

lib/compiler/test/guard_SUITE.erl

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,11 +3440,11 @@ is_integer_3_guard(_Config) ->
34403440
false = is_integer_3_guard_3(id(1024)),
34413441
true = is_integer_3_guard_3(id(1025)),
34423442

3443-
true = is_integer_3_guard_4(id(2), id(5)),
3444-
false = is_integer_3_guard_4(id(2), id(0)),
3445-
false = is_integer_3_guard_4(id(5), id(3)),
3446-
false = is_integer_3_guard_4(id(1024), id(1023)),
3447-
true = is_integer_3_guard_4(id(1025), id(1026)),
3443+
1 = is_integer_3_guard_4(id(1), id(0), id(5)),
3444+
false = is_integer_3_guard_4(id(1), id(-1), id(0)),
3445+
3446+
2 = is_integer_3_guard_5(id(2), id(0), id(9)),
3447+
false = is_integer_3_guard_5(id(1024), id(0), id(9)),
34483448

34493449
ok.
34503450

@@ -3463,11 +3463,18 @@ is_integer_3_guard_3(X) when not is_integer(X, 1, 1024) ->
34633463
is_integer_3_guard_3(X) ->
34643464
not is_integer(X, 1, 1024).
34653465

3466-
is_integer_3_guard_4(X, Y) when is_integer(X, 1, Y) ->
3467-
true = is_integer(X, 1, Y);
3468-
is_integer_3_guard_4(X, Y) when is_integer(X, Y, 1)->
3469-
is_integer(X, Y, 1);
3470-
is_integer_3_guard_4(_, _) -> false.
3466+
is_integer_3_guard_4(X, LB, UB) when 0 =< LB, UB < 10, is_integer(X, LB, UB) ->
3467+
is_integer_id(X);
3468+
is_integer_3_guard_4(X, LB, UB) ->
3469+
is_integer(X, LB, UB).
3470+
3471+
is_integer_3_guard_5(X, LB, UB) when 0 =< LB, is_integer(UB),
3472+
UB < 10, is_integer(X, LB, UB) ->
3473+
is_integer_id(X);
3474+
is_integer_3_guard_5(X, LB, UB) ->
3475+
is_integer(X, LB, UB).
3476+
3477+
is_integer_id(I) -> I.
34713478

34723479
%% Call this function to turn off constant propagation.
34733480
id(I) -> I.

0 commit comments

Comments
 (0)