aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2014-04-09 12:40:34 +0200
committerHans Bolinder <[email protected]>2014-04-29 09:17:01 +0200
commit4f0b3948eae361c04a3ed565a475a5d38f3c876d (patch)
tree5c72b9bef3aa9cf70f8054fd4b04bb08906e1b48
parent7ad783d431738c42fa9ce395fbc776916d927eb6 (diff)
downloadotp-4f0b3948eae361c04a3ed565a475a5d38f3c876d.tar.gz
otp-4f0b3948eae361c04a3ed565a475a5d38f3c876d.tar.bz2
otp-4f0b3948eae361c04a3ed565a475a5d38f3c876d.zip
Fix a -callback attribute bug
sys_pre_expand used to crash. There is no known reason to allow -callback attributes with explicit module.
-rw-r--r--lib/stdlib/src/erl_lint.erl23
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl25
2 files changed, 33 insertions, 15 deletions
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 3d33c3447b..0af2aa5044 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -357,8 +357,10 @@ format_error({type_syntax, Constr}) ->
io_lib:format("bad ~w type", [Constr]);
format_error({redefine_spec, {M, F, A}}) ->
io_lib:format("spec for ~w:~w/~w already defined", [M, F, A]);
-format_error({redefine_callback, {M, F, A}}) ->
- io_lib:format("callback ~w:~w/~w already defined", [M, F, A]);
+format_error({redefine_callback, {F, A}}) ->
+ io_lib:format("callback ~w/~w already defined", [F, A]);
+format_error({bad_callback, {M, F, A}}) ->
+ io_lib:format("explicit module not allowed for callback ~w:~w/~w ", [M, F, A]);
format_error({spec_fun_undefined, {M, F, A}}) ->
io_lib:format("spec for undefined function ~w:~w/~w", [M, F, A]);
format_error({missing_spec, {F,A}}) ->
@@ -2884,14 +2886,15 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
callback_decl(Line, MFA0, TypeSpecs,
St0 = #lint{callbacks = Callbacks, module = Mod}) ->
- MFA = case MFA0 of
- {F, Arity} -> {Mod, F, Arity};
- {_M, _F, Arity} -> MFA0
- end,
- St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},
- case dict:is_key(MFA, Callbacks) of
- true -> add_error(Line, {redefine_callback, MFA}, St1);
- false -> check_specs(TypeSpecs, Arity, St1)
+ case MFA0 of
+ {_M, _F, _A} -> add_error(Line, {bad_callback, MFA0}, St0);
+ {F, Arity} ->
+ MFA = {Mod, F, Arity},
+ St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},
+ case dict:is_key(MFA, Callbacks) of
+ true -> add_error(Line, {redefine_callback, MFA0}, St1);
+ false -> check_specs(TypeSpecs, Arity, St1)
+ end
end.
%% optional_callbacks(Line, FAs, State) -> State.
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 580ff79584..16bd88938a 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -3248,7 +3248,7 @@ otp_11861(Conf) when is_list(Conf) ->
-callback b(_) -> atom().
">>,
[],
- {errors,[{3,erl_lint,{redefine_callback,{lint_test,b,1}}}],[]}},
+ {errors,[{3,erl_lint,{redefine_callback,{b,1}}}],[]}},
{otp_11861_17,
<<"
-behaviour(bad_behaviour2).
@@ -3664,11 +3664,11 @@ maps_type(Config) when is_list(Config) ->
ok.
otp_11851(doc) ->
- "OTP-11851: More atoms can be used as type names.";
+ "OTP-11851: More atoms can be used as type names + bug fixes.";
otp_11851(Config) when is_list(Config) ->
Ts = [
- {otp_11851,
- <<"
+ {otp_11851_1,
+ <<"-export([t/0]).
-type range(A, B) :: A | B.
-type union(A) :: A.
@@ -3705,7 +3705,22 @@ otp_11851(Config) when is_list(Config) ->
a.
">>,
[],
- []}
+ []},
+ {otp_11851_2,
+ <<"-export([a/1, b/1, t/0]).
+
+ -callback b(_) -> integer().
+
+ -callback ?MODULE:a(_) -> integer().
+
+ a(_) -> 3.
+
+ b(_) -> a.
+
+ t()-> a.
+ ">>,
+ [],
+ {errors,[{5,erl_lint,{bad_callback,{lint_test,a,1}}}],[]}}
],
[] = run(Config, Ts),
ok.