From 6ab59ee359373043f0bb5950b63d7590cd54a3f9 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Wed, 22 Aug 2012 10:32:40 +0200 Subject: Allow non-ASCII characters in Xref filanmes Xref now accepts filenames with character codes greater than 126. (Thanks to Emile Joubert for reporting the issue.) --- lib/tools/src/xref_utils.erl | 4 ++-- lib/tools/test/xref_SUITE.erl | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/tools/src/xref_utils.erl b/lib/tools/src/xref_utils.erl index 9d4a175d88..680563e9df 100644 --- a/lib/tools/src/xref_utils.erl +++ b/lib/tools/src/xref_utils.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% Copyright Ericsson AB 2000-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -141,7 +141,7 @@ is_string([], _) -> is_string(Term, C) -> is_string1(Term, C). -is_string1([H | T], C) when H > C, H < 127 -> +is_string1([H | T], C) when H > C -> is_string1(T, C); is_string1([], _) -> true; diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index 78e49044a5..fd3e111d8d 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -53,7 +53,7 @@ analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]). -export([ - format_error/1, otp_7423/1, otp_7831/1]). + format_error/1, otp_7423/1, otp_7831/1, otp_10192/1]). -import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]). @@ -86,7 +86,7 @@ groups() -> fun_mfa_r14, fun_mfa_vars, qlc]}, {analyses, [], [analyze, basic, md, q, variables, unused_locals]}, - {misc, [], [format_error, otp_7423, otp_7831]}]. + {misc, [], [format_error, otp_7423, otp_7831, otp_10192]}]. init_per_suite(Config) -> init(Config). @@ -2515,6 +2515,18 @@ otp_7831(Conf) when is_list(Conf) -> ?line xref:stop(Pid2), ok. +otp_10192(suite) -> []; +otp_10192(doc) -> + ["OTP-10192. Allow filenames with character codes greater than 126."]; +otp_10192(Conf) when is_list(Conf) -> + PrivDir = ?privdir, + {ok, _Pid} = xref:start(s), + Dir = filename:join(PrivDir, "ä"), + ok = file:make_dir(Dir), + {ok, []} = xref:add_directory(s, Dir), + xref:stop(s), + ok. + %%% %%% Utilities %%% -- cgit v1.2.3 From e4e5d08621137473674cf3cdce0b36a43a8d6d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 22 Aug 2012 14:54:45 +0200 Subject: compiler: Warn if the size of a binary segment is invalid The compiler would silently accept and Dialyzer would crash on code like: <> It is never acceptable for Dialyzer to crash. The compiler should at least generate a warning for such code. It is tempting to let the compiler generate an error, but that would mean that code like: Sz = 42.0, <>. would be possible to compile with optimizations disabled, but not with optimizations enabled. Dialyzer crashes because it calls cerl:bitstr_bitsize/1, which crashes if the type of size for the segment is invalid. The easiest way to avoid that crash is to extend the sanity checks in v3_core to also include the size field of binary segments. That will cause the compiler to issue a warning and to replace the bad binary construction with a call to erlang:error/1. (It also means that Dialyzer will not issue a warning for bad size fields.) --- lib/compiler/src/v3_core.erl | 7 +++++++ lib/compiler/src/v3_kernel.erl | 7 +++++-- lib/compiler/test/bs_construct_SUITE.erl | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 242196c593..01042cc56f 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -823,6 +823,13 @@ bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) -> {_,_} -> throw(bad_binary) end, + case Size1 of + #c_var{} -> ok; + #c_literal{val=Sz} when is_integer(Sz), Sz >= 0 -> ok; + #c_literal{val=undefined} -> ok; + #c_literal{val=all} -> ok; + _ -> throw(bad_binary) + end, {#c_bitstr{val=E1,size=Size1, unit=#c_literal{val=Unit}, type=#c_literal{val=Type}, diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index c4e7b45aac..b184987625 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -278,11 +278,12 @@ expr(#c_binary{anno=A,segments=Cv}, Sub, St0) -> {#k_binary{anno=A,segs=Kv},Ep,St1} catch throw:bad_element_size -> + St1 = add_warning(get_line(A), bad_segment_size, A, St0), Erl = #c_literal{val=erlang}, Name = #c_literal{val=error}, Args = [#c_literal{val=badarg}], Error = #c_call{anno=A,module=Erl,name=Name,args=Args}, - expr(Error, Sub, St0) + expr(Error, Sub, St1) end; expr(#c_fun{anno=A,vars=Cvs,body=Cb}, Sub0, #kern{ff=OldFF,func=Func}=St0) -> FA = case OldFF of @@ -1827,7 +1828,9 @@ format_error({nomatch_shadow,Line}) -> format_error(nomatch_shadow) -> "this clause cannot match because a previous clause always matches"; format_error(bad_call) -> - "invalid module and/or function name; this call will always fail". + "invalid module and/or function name; this call will always fail"; +format_error(bad_segment_size) -> + "binary construction will fail because of a type mismatch". add_warning(none, Term, Anno, #kern{ws=Ws}=St) -> File = get_file(Anno), diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl index 31c7890f26..e8b30f44ce 100644 --- a/lib/compiler/test/bs_construct_SUITE.erl +++ b/lib/compiler/test/bs_construct_SUITE.erl @@ -468,6 +468,10 @@ opt(Config) when is_list(Config) -> ?line {'EXIT',_} = (catch <<<<23,56,0,2>>:64/float>>), ?line {'EXIT',_} = (catch <<<<23,56,0,2:7>>/binary>>), + %% Test constant propagation - there should be a warning. + BadSz = 2.5, + {'EXIT',_} = (catch <<<>:BadSz/binary>>), + case id(false) of true -> ?line opt_dont_call_me(); false -> ok -- cgit v1.2.3 From 0994710c308990a04ca1245c894e4e373e55bcec Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 22 Aug 2012 18:09:17 +0200 Subject: Revert "Merge branch 'nox/compile-column-numbers' into maint" Column numbers was merged without understanding all the whole story. See mail on erlang-patches for details. This reverts commit df8e67e203b83f95d1e098fec88ad5d0ad840069, reversing changes made to 0c9d90f314f364e5b1301ec89d762baabc57c7aa. --- lib/compiler/doc/src/compile.xml | 5 ----- lib/compiler/src/compile.erl | 25 ++++------------------ lib/compiler/test/error_SUITE.erl | 15 ++----------- lib/stdlib/doc/src/epp.xml | 2 -- lib/stdlib/src/epp.erl | 44 ++++++++------------------------------- lib/stdlib/src/erl_scan.erl | 2 +- 6 files changed, 16 insertions(+), 77 deletions(-) (limited to 'lib') diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index b87e32a3d9..be9eb1cd75 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -108,11 +108,6 @@ See the Efficiency Guide for further information.

- column - -

The compiler will keep the column numbers while parsing.

-
- compressed

The compiler will compress the generated object code, diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index fbaacc08da..7365706b94 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -41,7 +41,7 @@ -type option() :: atom() | {atom(), term()} | {'d', atom(), term()}. --type err_info() :: erl_scan:error_info(). %% ErrorDescriptor +-type err_info() :: {erl_scan:line(), module(), term()}. %% ErrorDescriptor -type errors() :: [{file:filename(), [err_info()]}]. -type warnings() :: [{file:filename(), [err_info()]}]. -type mod_ret() :: {'ok', module()} @@ -363,17 +363,7 @@ messages_per_file(Ms) -> (_) -> false end, A) end, T, PrioMs), - Prio = lists:sort(fun({_,{As1,_,_}}, {_,{As2,_,_}}) -> - {location, Loc1} = - erl_scan:attributes_info(As1, location), - {location, Loc2} = - erl_scan:attributes_info(As2, location), - case {Loc1, Loc2} of - {{L1, _}, L2} when is_integer(L2) -> L1 < L2; - {L1, {L2, _}} when is_integer(L1) -> L1 =< L2; - {_, _} -> Loc1 =< Loc2 - end - end, + Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end, lists:append(Prio0)), flatmap(fun mpf/1, [Prio, Rest]). @@ -783,8 +773,7 @@ parse_module(St) -> Opts = St#compile.options, Cwd = ".", IncludePath = [Cwd, St#compile.dir|inc_paths(Opts)], - AtPos = initial_position(Opts), - R = epp:parse_file(St#compile.ifile, AtPos, IncludePath, pre_defs(Opts)), + R = epp:parse_file(St#compile.ifile, IncludePath, pre_defs(Opts)), case R of {ok,Forms} -> {ok,St#compile{code=Forms}}; @@ -1434,7 +1423,7 @@ report_warnings(#compile{options=Opts,warnings=Ws0}) -> end. format_message(F, P, [{{Line,Column}=Loc,Mod,E}|Es]) -> - M = {{F,Loc},io_lib:format("~s:~w:~w: ~s~s\n", + M = {{F,Loc},io_lib:format("~s:~w:~w ~s~s\n", [F,Line,Column,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; format_message(F, P, [{Line,Mod,E}|Es]) -> @@ -1490,12 +1479,6 @@ objfile(Base, St) -> tmpfile(Ofile) -> reverse([$#|tl(reverse(Ofile))]). -initial_position(Opts) -> - case lists:member(column, Opts) of - true -> {1, 1}; - false -> 1 - end. - %% pre_defs(Options) %% inc_paths(Options) %% Extract the predefined macros and include paths from the option list. diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl index 47698ecdb7..eb5e50818e 100644 --- a/lib/compiler/test/error_SUITE.erl +++ b/lib/compiler/test/error_SUITE.erl @@ -22,15 +22,13 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1, - column_number/1 - ]). + head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> test_lib:recompile(?MODULE), - [head_mismatch_line, warnings_as_errors, bif_clashes, column_number]. + [head_mismatch_line, warnings_as_errors, bif_clashes]. groups() -> []. @@ -168,15 +166,6 @@ bif_clashes(Config) when is_list(Config) -> -%% Tests that messages are correctly reported with column numbers -%% if the column option is set. -column_number(Config) when is_list(Config) -> - Ts1 = [{column_number_warning, - <<"\nt(X) -> ok.">>, - [return_warnings, export_all, column], - {warning, [{{2, 3}, erl_lint, {unused_var, 'X'}}]}}], - ?line [] = run(Config, Ts1), - ok. %% Tests that a head mismatch is reported on the correct line (OTP-2125). head_mismatch_line(Config) when is_list(Config) -> diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml index a57c7084fa..488499581f 100644 --- a/lib/stdlib/doc/src/epp.xml +++ b/lib/stdlib/doc/src/epp.xml @@ -51,7 +51,6 @@ - Open a file for preprocessing

Opens a file for preprocessing.

@@ -76,7 +75,6 @@ - Preprocess and parse an Erlang source file

Preprocesses and parses an Erlang source file. diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index d958b0af2a..ccc14610d7 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -20,9 +20,9 @@ %% An Erlang code preprocessor. --export([open/2,open/3,open/4, open/5,close/1,format_error/1]). +-export([open/2,open/3,open/5,close/1,format_error/1]). -export([scan_erl_form/1,parse_erl_form/1,macro_defs/1]). --export([parse_file/1, parse_file/3, parse_file/4]). +-export([parse_file/1, parse_file/3]). -export([interpret_file_attribute/1]). -export([normalize_typed_record_fields/1,restore_typed_record_fields/1]). @@ -54,14 +54,12 @@ %% open(FileName, IncludePath) %% open(FileName, IncludePath, PreDefMacros) -%% open(FileName, StartLocation, IncludePath, PredefMacros) %% open(FileName, IoDevice, StartLocation, IncludePath, PreDefMacros) %% close(Epp) %% scan_erl_form(Epp) %% parse_erl_form(Epp) %% parse_file(Epp) %% parse_file(FileName, IncludePath, PreDefMacros) -%% parse_file(FileName, StartLocation, IncludePath, PreDefMacros) %% macro_defs(Epp) -spec open(FileName, IncludePath) -> @@ -83,20 +81,8 @@ open(Name, Path) -> ErrorDescriptor :: term(). open(Name, Path, Pdm) -> - open(Name, 1, Path, Pdm). - --spec open(FileName, StartLocation, IncludePath, PredefMacros) -> - {'ok', Epp} | {'error', ErrorDescriptor} when - FileName :: file:name(), - StartLocation :: erl_scan:location(), - IncludePath :: [DirectoryName :: file:name()], - PredefMacros :: macros(), - Epp :: epp_handle(), - ErrorDescriptor :: term(). - -open(Name, StartLocation, Path, Pdm) -> Self = self(), - Epp = spawn(fun() -> server(Self, Name, StartLocation, Path, Pdm) end), + Epp = spawn(fun() -> server(Self, Name, Path, Pdm) end), epp_request(Epp). open(Name, File, StartLocation, Path, Pdm) -> @@ -192,21 +178,7 @@ format_error(E) -> file:format_error(E). OpenError :: file:posix() | badarg | system_limit. parse_file(Ifile, Path, Predefs) -> - parse_file(Ifile, 1, Path, Predefs). - --spec parse_file(FileName, StartLocation, IncludePath, PredefMacros) -> - {'ok', [Form]} | {error, OpenError} when - FileName :: file:name(), - StartLocation :: erl_scan:location(), - IncludePath :: [DirectoryName :: file:name()], - Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line}, - PredefMacros :: macros(), - Line :: erl_scan:line(), - ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), - OpenError :: file:posix() | badarg | system_limit. - -parse_file(Ifile, StartLocation, Path, Predefs) -> - case open(Ifile, StartLocation, Path, Predefs) of + case open(Ifile, Path, Predefs) of {ok,Epp} -> Forms = parse_file(Epp), close(Epp), @@ -273,12 +245,14 @@ restore_typed_record_fields([{attribute,La,type,{{record,Record},Fields,[]}}| restore_typed_record_fields([Form|Forms]) -> [Form|restore_typed_record_fields(Forms)]. -%% server(StarterPid, FileName, Location, Path, PreDefMacros) -server(Pid, Name, AtLocation, Path, Pdm) -> +%% server(StarterPid, FileName, Path, PreDefMacros) + +server(Pid, Name, Path, Pdm) -> process_flag(trap_exit, true), case file:open(Name, [read]) of {ok,File} -> - init_server(Pid, Name, File, AtLocation, Path, Pdm, false); + Location = 1, + init_server(Pid, Name, File, Location, Path, Pdm, false); {error,E} -> epp_reply(Pid, {error,E}) end. diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl index be64b428b1..10b2ed2e49 100644 --- a/lib/stdlib/src/erl_scan.erl +++ b/lib/stdlib/src/erl_scan.erl @@ -55,7 +55,7 @@ token_info/1,token_info/2, attributes_info/1,attributes_info/2,set_attribute/3]). --export_type([error_info/0, line/0, location/0, tokens_result/0]). +-export_type([error_info/0, line/0, tokens_result/0]). %%% %%% Defines and type definitions -- cgit v1.2.3