aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/compile_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/test/compile_SUITE.erl')
-rw-r--r--lib/compiler/test/compile_SUITE.erl240
1 files changed, 148 insertions, 92 deletions
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index be01ea713d..df401ccc2b 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. 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
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -24,13 +25,13 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- app_test/1,
+ app_test/1,appup_test/1,
file_1/1, forms_2/1, module_mismatch/1, big_file/1, outdir/1,
binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1,
other_output/1, encrypted_abstr/1,
bad_record_use1/1, bad_record_use2/1, strict_record/1,
missing_testheap/1, cover/1, env/1, core/1, asm/1,
- sys_pre_attributes/1]).
+ sys_pre_attributes/1, dialyzer/1]).
-export([init/3]).
@@ -42,12 +43,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [app_test, file_1, forms_2, module_mismatch, big_file, outdir,
+ [app_test, appup_test, file_1, forms_2, module_mismatch, big_file, outdir,
binary, makedep, cond_and_ifdef, listings, listings_big,
other_output, encrypted_abstr,
{group, bad_record_use}, strict_record,
missing_testheap, cover, env, core, asm,
- sys_pre_attributes].
+ sys_pre_attributes, dialyzer].
groups() ->
[{bad_record_use, [],
@@ -71,6 +72,10 @@ end_per_group(_GroupName, Config) ->
app_test(Config) when is_list(Config) ->
?line ?t:app_test(compiler).
+%% Test that the Application upgrade file has no `basic' errors.";
+appup_test(Config) when is_list(Config) ->
+ ok = ?t:appup_test(compiler).
+
%% Tests that we can compile and run a simple Erlang program,
%% using compile:file/1.
@@ -98,6 +103,8 @@ file_1(Config) when is_list(Config) ->
?line compile_and_verify(Simple, Target, [debug_info]),
?line {ok,simple} = compile:file(Simple, [no_line_info]), %Coverage
+ {ok,simple} = compile:file(Simple, [{eprof,beam_z}]), %Coverage
+
?line ok = file:set_cwd(Cwd),
?line true = exists(Target),
?line passed = run(Target, test, []),
@@ -120,7 +127,8 @@ file_1(Config) when is_list(Config) ->
forms_2(Config) when is_list(Config) ->
Src = "/foo/bar",
AbsSrc = filename:absname(Src),
- {ok,simple,Binary} = compile:forms([{attribute,1,module,simple}],
+ Anno = erl_anno:new(1),
+ {ok,simple,Binary} = compile:forms([{attribute,Anno,module,simple}],
[binary,{source,Src}]),
code:load_binary(simple, Src, Binary),
Info = simple:module_info(compile),
@@ -286,57 +294,67 @@ cond_and_ifdef(Config) when is_list(Config) ->
ok.
listings(Config) when is_list(Config) ->
- ?line Dog = test_server:timetrap(test_server:minutes(8)),
- ?line DataDir = ?config(data_dir, Config),
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Simple = filename:join(DataDir, simple),
- ?line TargetDir = filename:join(PrivDir, listings),
- ?line ok = file:make_dir(TargetDir),
+ Dog = test_server:timetrap(test_server:minutes(8)),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ok = do_file_listings(DataDir, PrivDir, [
+ "simple",
+ "small",
+ "small_maps"
+ ]),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+do_file_listings(_, _, []) -> ok;
+do_file_listings(DataDir, PrivDir, [File|Files]) ->
+ Simple = filename:join(DataDir, File),
+ TargetDir = filename:join(PrivDir, listings),
+ ok = file:make_dir(TargetDir),
%% Test all dedicated listing options.
- ?line do_listing(Simple, TargetDir, 'S'),
- ?line do_listing(Simple, TargetDir, 'E'),
- ?line do_listing(Simple, TargetDir, 'P'),
- ?line do_listing(Simple, TargetDir, dpp, ".pp"),
- ?line do_listing(Simple, TargetDir, dabstr, ".abstr"),
- ?line do_listing(Simple, TargetDir, dexp, ".expand"),
- ?line do_listing(Simple, TargetDir, dcore, ".core"),
- ?line do_listing(Simple, TargetDir, doldinline, ".oldinline"),
- ?line do_listing(Simple, TargetDir, dinline, ".inline"),
- ?line do_listing(Simple, TargetDir, dcore, ".core"),
- ?line do_listing(Simple, TargetDir, dcopt, ".copt"),
- ?line do_listing(Simple, TargetDir, dsetel, ".dsetel"),
- ?line do_listing(Simple, TargetDir, dkern, ".kernel"),
- ?line do_listing(Simple, TargetDir, dlife, ".life"),
- ?line do_listing(Simple, TargetDir, dcg, ".codegen"),
- ?line do_listing(Simple, TargetDir, dblk, ".block"),
- ?line do_listing(Simple, TargetDir, dbool, ".bool"),
- ?line do_listing(Simple, TargetDir, dtype, ".type"),
- ?line do_listing(Simple, TargetDir, ddead, ".dead"),
- ?line do_listing(Simple, TargetDir, djmp, ".jump"),
- ?line do_listing(Simple, TargetDir, dclean, ".clean"),
- ?line do_listing(Simple, TargetDir, dpeep, ".peep"),
- ?line do_listing(Simple, TargetDir, dopt, ".optimize"),
+ do_listing(Simple, TargetDir, 'S'),
+ do_listing(Simple, TargetDir, 'E'),
+ do_listing(Simple, TargetDir, 'P'),
+ do_listing(Simple, TargetDir, dpp, ".pp"),
+ do_listing(Simple, TargetDir, dabstr, ".abstr"),
+ do_listing(Simple, TargetDir, dexp, ".expand"),
+ do_listing(Simple, TargetDir, dcore, ".core"),
+ do_listing(Simple, TargetDir, doldinline, ".oldinline"),
+ do_listing(Simple, TargetDir, dinline, ".inline"),
+ do_listing(Simple, TargetDir, dcore, ".core"),
+ do_listing(Simple, TargetDir, dcopt, ".copt"),
+ do_listing(Simple, TargetDir, dsetel, ".dsetel"),
+ do_listing(Simple, TargetDir, dkern, ".kernel"),
+ do_listing(Simple, TargetDir, dlife, ".life"),
+ do_listing(Simple, TargetDir, dcg, ".codegen"),
+ do_listing(Simple, TargetDir, dblk, ".block"),
+ do_listing(Simple, TargetDir, dbool, ".bool"),
+ do_listing(Simple, TargetDir, dtype, ".type"),
+ do_listing(Simple, TargetDir, ddead, ".dead"),
+ do_listing(Simple, TargetDir, djmp, ".jump"),
+ do_listing(Simple, TargetDir, dclean, ".clean"),
+ do_listing(Simple, TargetDir, dpeep, ".peep"),
+ do_listing(Simple, TargetDir, dopt, ".optimize"),
%% First clean up.
- ?line Listings = filename:join(PrivDir, listings),
- ?line lists:foreach(fun(F) -> ok = file:delete(F) end,
- filelib:wildcard(filename:join(Listings, "*"))),
+ Listings = filename:join(PrivDir, listings),
+ lists:foreach(fun(F) -> ok = file:delete(F) end,
+ filelib:wildcard(filename:join(Listings, "*"))),
%% Test options that produce a listing file if 'binary' is not given.
- ?line do_listing(Simple, TargetDir, to_pp, ".P"),
- ?line do_listing(Simple, TargetDir, to_exp, ".E"),
- ?line do_listing(Simple, TargetDir, to_core0, ".core"),
- ?line ok = file:delete(filename:join(Listings, "simple.core")),
- ?line do_listing(Simple, TargetDir, to_core, ".core"),
- ?line do_listing(Simple, TargetDir, to_kernel, ".kernel"),
+ do_listing(Simple, TargetDir, to_pp, ".P"),
+ do_listing(Simple, TargetDir, to_exp, ".E"),
+ do_listing(Simple, TargetDir, to_core0, ".core"),
+ ok = file:delete(filename:join(Listings, File ++ ".core")),
+ do_listing(Simple, TargetDir, to_core, ".core"),
+ do_listing(Simple, TargetDir, to_kernel, ".kernel"),
%% Final clean up.
- ?line lists:foreach(fun(F) -> ok = file:delete(F) end,
- filelib:wildcard(filename:join(Listings, "*"))),
- ?line ok = file:del_dir(Listings),
- ?line test_server:timetrap_cancel(Dog),
- ok.
+ lists:foreach(fun(F) -> ok = file:delete(F) end,
+ filelib:wildcard(filename:join(Listings, "*"))),
+ ok = file:del_dir(Listings),
+
+ do_file_listings(DataDir,PrivDir,Files).
listings_big(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:minutes(10)),
@@ -351,7 +369,7 @@ listings_big(Config) when is_list(Config) ->
?line do_listing(Big, TargetDir, dkern, ".kernel"),
?line Target = filename:join(TargetDir, big),
- ?line {ok,big} = compile:file(Target, [asm,{outdir,TargetDir}]),
+ {ok,big} = compile:file(Target, [from_asm,{outdir,TargetDir}]),
%% Cleanup.
?line ok = file:delete(Target ++ ".beam"),
@@ -415,11 +433,11 @@ encrypted_abstr(Config) when is_list(Config) ->
?line {Simple,Target} = files(Config, "encrypted_abstr"),
Res = case has_crypto() of
- no ->
+ false ->
%% No crypto.
?line encrypted_abstr_no_crypto(Simple, Target),
{comment,"The crypto application is missing or broken"};
- yes ->
+ true ->
%% Simulate not having crypto by removing
%% the crypto application from the path.
?line OldPath = code:get_path(),
@@ -511,6 +529,7 @@ write_crypt_file(Contents0) ->
ok = file:write_file(".erlang.crypt", Contents).
encrypted_abstr_no_crypto(Simple, Target) ->
+ io:format("simpe: ~p~n", [Simple]),
?line TargetDir = filename:dirname(Target),
?line Key = "ablurf123BX#$;3",
?line error = compile:file(Simple,
@@ -525,11 +544,11 @@ verify_abstract(Target) ->
has_crypto() ->
try
crypto:start(),
- crypto:info(),
+ <<_,_,_,_,_>> = crypto:rand_bytes(5),
crypto:stop(),
- yes
+ true
catch
- error:_ -> no
+ error:_ -> false
end.
install_crypto_key(Key) ->
@@ -733,44 +752,67 @@ env_1(Simple, Target) ->
%% compile the generated Core Erlang files.
core(Config) when is_list(Config) ->
- ?line Dog = test_server:timetrap(test_server:minutes(5)),
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Outdir = filename:join(PrivDir, "core"),
- ?line ok = file:make_dir(Outdir),
+ PrivDir = ?config(priv_dir, Config),
+ Outdir = filename:join(PrivDir, "core"),
+ ok = file:make_dir(Outdir),
- ?line Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
- ?line TestBeams = filelib:wildcard(Wc),
- ?line Abstr = [begin {ok,{Mod,[{abstract_code,
+ Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
+ TestBeams = filelib:wildcard(Wc),
+ Abstr = [begin {ok,{Mod,[{abstract_code,
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
{Mod,Abstr} end || Beam <- TestBeams],
- ?line Res = test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr),
- ?line test_server:timetrap_cancel(Dog),
- Res.
-
+ test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr).
do_core({M,A}, Outdir) ->
try
- {ok,M,Core} = compile:forms(A, [to_core,report]),
- CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
- CorePP = core_pp:format(Core),
- ok = file:write_file(CoreFile, CorePP),
- case compile:file(CoreFile, [clint,from_core,binary]) of
- {ok,M,_} ->
- ok = file:delete(CoreFile);
- Other ->
- io:format("*** core_lint failure '~p' for ~s\n",
- [Other,CoreFile]),
- error
- end
- catch Class:Error ->
+ do_core_1(M, A, Outdir)
+ catch
+ throw:{error,Error} ->
+ io:format("*** compilation failure '~p' for module ~s\n",
+ [Error,M]),
+ error;
+ Class:Error ->
io:format("~p: ~p ~p\n~p\n",
[M,Class,Error,erlang:get_stacktrace()]),
error
end.
-%% Compile to Beam assembly language (.S) and the try to
-%% run .S throught the compiler again.
+do_core_1(M, A, Outdir) ->
+ {ok,M,Core0} = compile:forms(A, [to_core]),
+ CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
+ CorePP = core_pp:format(Core0),
+ ok = file:write_file(CoreFile, CorePP),
+
+ %% Parse the .core file and return the result as Core Erlang Terms.
+ Core = case compile:file(CoreFile, [report_errors,from_core,no_copt,to_core,binary]) of
+ {ok,M,Core1} -> Core1;
+ Other -> throw({error,Other})
+ end,
+ ok = file:delete(CoreFile),
+
+ %% Compile as usual (including optimizations).
+ compile_forms(Core, [clint,from_core,binary]),
+
+ %% Don't optimize to test that we are not dependent
+ %% on the Core Erlang optmimization passes.
+ %% (Example of a previous bug: The core_parse pass
+ %% would not turn map literals into #c_literal{}
+ %% records; if sys_core_fold was run it would fix
+ %% that; if sys_core_fold was not run v3_kernel would
+ %% crash.)
+ compile_forms(Core, [clint,from_core,no_copt,binary]),
+
+ ok.
+
+compile_forms(Forms, Opts) ->
+ case compile:forms(Forms, [report_errors|Opts]) of
+ {ok,[],_} -> ok;
+ Other -> throw({error,Other})
+ end.
+
+%% Compile to Beam assembly language (.S) and then try to
+%% run .S through the compiler again.
asm(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:minutes(20)),
@@ -791,10 +833,10 @@ do_asm(Beam, Outdir) ->
try
{ok,M,Asm} = compile:forms(A, ['S']),
AsmFile = filename:join(Outdir, atom_to_list(M)++".S"),
- {ok,Fd} = file:open(AsmFile, [write]),
+ {ok,Fd} = file:open(AsmFile, [write,{encoding,utf8}]),
beam_listing:module(Fd, Asm),
ok = file:close(Fd),
- case compile:file(AsmFile, [from_asm,no_postopt,binary,report]) of
+ case compile:file(AsmFile, [from_asm,binary,report]) of
{ok,M,_} ->
ok = file:delete(AsmFile);
Other ->
@@ -839,6 +881,20 @@ sys_pre_attributes(Config) ->
[report,verbose]),
ok.
+%% Test the dialyzer option to cover more code.
+dialyzer(Config) ->
+ Priv = ?config(priv_dir, Config),
+ file:set_cwd(?config(data_dir, Config)),
+ Opts = [{outdir,Priv},report_errors],
+ M = dialyzer_test,
+ {ok,M} = c:c(M, [dialyzer|Opts]),
+ [{a,b,c}] = M:M(),
+
+ %% Cover huge line numbers without the 'dialyzer' option.
+ {ok,M} = c:c(M, Opts),
+ [{a,b,c}] = M:M(),
+ ok.
+
%%%
%%% Utilities.
%%%