diff options
author | Hans Bolinder <[email protected]> | 2014-04-09 12:40:34 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2014-04-29 09:17:01 +0200 |
commit | 4f0b3948eae361c04a3ed565a475a5d38f3c876d (patch) | |
tree | 5c72b9bef3aa9cf70f8054fd4b04bb08906e1b48 | |
parent | 7ad783d431738c42fa9ce395fbc776916d927eb6 (diff) | |
download | otp-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.erl | 23 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 25 |
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. |