diff options
author | Björn Gustavsson <[email protected]> | 2016-08-15 15:34:06 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-09-02 14:24:36 +0200 |
commit | 0baa07cdf2754748bbc2d969bf83f08c0976fb78 (patch) | |
tree | b5d649dbe4778d8488ae09a99e68435adc216342 /lib/debugger/src/dbg_iload.erl | |
parent | 8a04dd4dd2d479efe488b0bed118e10559835fb6 (diff) | |
download | otp-0baa07cdf2754748bbc2d969bf83f08c0976fb78.tar.gz otp-0baa07cdf2754748bbc2d969bf83f08c0976fb78.tar.bz2 otp-0baa07cdf2754748bbc2d969bf83f08c0976fb78.zip |
Fix overridden BIFs
The filters in a list comprehension can be guard expressions or
an ordinary expressions.
If a guard expression is used as a filter, an exception will basically
mean the same as 'false':
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, element(1, X) =:= some_tag]
%% Returns [{some_tag,42}]
On the other hand, if an ordinary expression is used as a filter, there
will be an exception:
my_element(N, T) -> element(N, T).
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, my_element(1, X) =:= some_tag]
%% Causes a 'badarg' exception when element(1, an_atom) is evaluated
It has been allowed for several releases to override a BIF with
a local function. Thus, if we define a function called element/2,
it will be called instead of the BIF element/2 within the module.
We must use the "erlang:" prefix to call the BIF.
Therefore, the following code is expected to work the same way as in
our second example above:
-compile({no_auto_import,[element/2]}).
element(N, T) ->
erlang:element(N, T).
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, element(1, X) =:= some_tag].
%% Causes a 'badarg' exception when element(1, an_atom) is evaluated
But the compiler refuses to compile the code with the following
diagnostic:
call to local/imported function element/2 is illegal in guard
Diffstat (limited to 'lib/debugger/src/dbg_iload.erl')
-rw-r--r-- | lib/debugger/src/dbg_iload.erl | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index 917f213e60..22e2073df8 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -486,30 +486,10 @@ expr({'try',Anno,Es0,CaseCs0,CatchCs0,As0}, Lc) -> CatchCs = icr_clauses(CatchCs0, Lc), As = expr_list(As0), {'try',ln(Anno),Es,CaseCs,CatchCs,As}; -expr({lc,Anno,E0,Gs0}, _Lc) -> %R8. - Gs = lists:map(fun ({generate,L,P0,Qs}) -> - {generate,L,pattern(P0),expr(Qs, false)}; - ({b_generate,L,P0,Qs}) -> %R12. - {b_generate,L,pattern(P0),expr(Qs, false)}; - (Expr) -> - case erl_lint:is_guard_test(Expr) of - true -> {guard,guard([[Expr]])}; - false -> expr(Expr, false) - end - end, Gs0), - {lc,ln(Anno),expr(E0, false),Gs}; -expr({bc,Anno,E0,Gs0}, _Lc) -> %R12. - Gs = lists:map(fun ({generate,L,P0,Qs}) -> - {generate,L,pattern(P0),expr(Qs, false)}; - ({b_generate,L,P0,Qs}) -> %R12. - {b_generate,L,pattern(P0),expr(Qs, false)}; - (Expr) -> - case erl_lint:is_guard_test(Expr) of - true -> {guard,guard([[Expr]])}; - false -> expr(Expr, false) - end - end, Gs0), - {bc,ln(Anno),expr(E0, false),Gs}; +expr({lc,_,_,_}=Compr, _Lc) -> + expr_lc_bc(Compr); +expr({bc,_,_,_}=Compr, _Lc) -> + expr_lc_bc(Compr); expr({match,Anno,P0,E0}, _Lc) -> E1 = expr(E0, false), P1 = pattern(P0), @@ -560,6 +540,23 @@ make_bit_type(_Line, Size, Type0) -> %Integer or 'all' {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0), {Size,erl_bits:as_list(Bt)}. +expr_lc_bc({Tag,Anno,E0,Gs0}) -> + Gs = lists:map(fun ({generate,L,P0,Qs}) -> + {generate,L,pattern(P0),expr(Qs, false)}; + ({b_generate,L,P0,Qs}) -> %R12. + {b_generate,L,pattern(P0),expr(Qs, false)}; + (Expr) -> + case is_guard_test(Expr) of + true -> {guard,guard([[Expr]])}; + false -> expr(Expr, false) + end + end, Gs0), + {Tag,ln(Anno),expr(E0, false),Gs}. + +is_guard_test(Expr) -> + IsOverridden = fun({_,_}) -> true end, + erl_lint:is_guard_test(Expr, [], IsOverridden). + %% The debugger converts both strings "abc" and lists [67, 68, 69] %% into {value, Line, [67, 68, 69]}, making it impossible to later %% distingish one or the other inside binaries when evaluating. To |