aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger/src/dbg_iload.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-08-15 15:34:06 +0200
committerBjörn Gustavsson <[email protected]>2016-09-02 14:24:36 +0200
commit0baa07cdf2754748bbc2d969bf83f08c0976fb78 (patch)
treeb5d649dbe4778d8488ae09a99e68435adc216342 /lib/debugger/src/dbg_iload.erl
parent8a04dd4dd2d479efe488b0bed118e10559835fb6 (diff)
downloadotp-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.erl45
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