aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/doc/src/compile.xml39
-rw-r--r--lib/compiler/doc/src/notes.xml2
-rw-r--r--lib/compiler/src/beam_asm.erl4
-rw-r--r--lib/compiler/src/beam_type.erl2
-rw-r--r--lib/compiler/src/beam_validator.erl18
-rw-r--r--lib/compiler/src/compile.erl99
-rw-r--r--lib/compiler/src/core_scan.erl2
-rw-r--r--lib/compiler/src/erl_bifs.erl3
-rwxr-xr-xlib/compiler/src/genop.tab2
-rw-r--r--lib/compiler/src/v3_core.erl14
-rw-r--r--lib/compiler/src/v3_kernel.erl4
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl2
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl13
-rw-r--r--lib/compiler/test/bs_construct_SUITE.erl21
-rw-r--r--lib/compiler/test/compilation_SUITE.erl4
-rw-r--r--lib/compiler/test/compile_SUITE.erl127
-rw-r--r--lib/compiler/test/compile_SUITE_data/small_float.erl5
-rw-r--r--lib/compiler/test/compiler.cover2
-rw-r--r--lib/compiler/test/lc_SUITE.erl2
-rw-r--r--lib/compiler/test/misc_SUITE.erl2
20 files changed, 254 insertions, 113 deletions
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index ed04dac1c0..10164890f2 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -132,12 +132,10 @@
<tag><c>debug_info</c></tag>
<item>
<marker id="debug_info"></marker>
- <p>Includes debug information in the form of abstract code
- (see
- <seealso marker="erts:absform">The Abstract Format</seealso>
- in ERTS User's Guide) in the compiled beam module. Tools
- such as Debugger, Xref, and Cover require
- the debug information to be included.</p>
+ <p>Includes debug information in the form of <seealso marker="erts:absform">
+ Erlang Abstract Format</seealso> in the <c>debug_info</c>
+ chunk of the compiled beam module. Tools such as Debugger,
+ Xref, and Cover require the debug information to be included.</p>
<p><em>Warning</em>: Source code can be reconstructed from
the debug information. Use encrypted debug information
@@ -147,6 +145,21 @@
<seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
+ <tag><c>{debug_info, {Backend, Data}}</c></tag>
+ <item>
+ <marker id="debug_info"></marker>
+ <p>Includes custom debug information in the form of a
+ <c>Backend</c> module with custom <c>Data</c> in the compiled beam module.
+ The given module must implement a <c>debug_info/4</c> function
+ and is responsible for generating different code representations,
+ as described in the <c>debug_info</c> under
+ <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
+
+ <p><em>Warning</em>: Source code can be reconstructed from
+ the debug information. Use encrypted debug information
+ (<c>encrypt_debug_info</c>) to prevent this.</p>
+ </item>
+
<tag><c>{debug_info_key,KeyString}</c></tag>
<item></item>
<tag><c>{debug_info_key,{Mode,KeyString}}</c></tag>
@@ -587,9 +600,9 @@ module.beam: module.erl \
to be deprecated.</p>
</item>
- <tag><c>warn_obsolete_guard</c></tag>
+ <tag><c>nowarn_obsolete_guard</c></tag>
<item>
- <p>Emits warnings for calls to old type testing BIFs,
+ <p>Turns off warnings for calls to old type testing BIFs,
such as <c>pid/1</c> and <c>list/1</c>. See the
<seealso marker="doc/reference_manual:expressions#guards">Erlang Reference Manual</seealso>
for a complete list of type testing BIFs and their old
@@ -616,6 +629,14 @@ module.beam: module.erl \
<p>Turns off warnings for unused record types. Default is to
emit warnings for unused locally defined record types.</p>
</item>
+
+ <tag><c>nowarn_get_stacktrace</c></tag>
+ <item>
+ <p>Turns off warnings for using <c>get_stacktrace/0</c> in a context
+ where it will probably not work in a future release. For example,
+ by default there will be a warning if <c>get_stacktrace/0</c> is
+ used following a <c>catch</c> expression.</p>
+ </item>
</taglist>
<p>Another class of warnings is generated by the compiler
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 449453bf88..1dc0c808e7 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index 1bda185acd..c35efdfc9d 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -194,7 +194,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, ExtraChunks, SourceFile, Opts,
Chunks = case member(slim, Opts) of
true ->
- [Essentials,AttrChunk,CheckedChunks];
+ [Essentials,AttrChunk];
false ->
[Essentials,LocChunk,AttrChunk,
CompileChunk,CheckedChunks,LineChunk]
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index 7e9a243ada..3d842a6fd3 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index c26e5719aa..f726625510 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -623,17 +623,17 @@ valfun_4({test,bs_skip_utf16,{f,Fail},[Ctx,Live,_]}, Vst) ->
valfun_4({test,bs_skip_utf32,{f,Fail},[Ctx,Live,_]}, Vst) ->
validate_bs_skip_utf(Fail, Ctx, Live, Vst);
valfun_4({test,bs_get_integer2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_float2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {float, []}, Dst, Vst);
valfun_4({test,bs_get_binary2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, term, Dst, Vst);
valfun_4({test,bs_get_utf8,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_utf16,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_utf32,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({bs_save2,Ctx,SavePoint}, Vst) ->
bsm_save(Ctx, SavePoint, Vst);
valfun_4({bs_restore2,Ctx,SavePoint}, Vst) ->
@@ -794,12 +794,12 @@ verify_put_map(Fail, Src, Dst, Live, List, Vst0) ->
%%
%% Common code for validating bs_get* instructions.
%%
-validate_bs_get(Fail, Ctx, Live, Dst, Vst0) ->
+validate_bs_get(Fail, Ctx, Live, Type, Dst, Vst0) ->
bsm_validate_context(Ctx, Vst0),
verify_live(Live, Vst0),
Vst1 = prune_x_regs(Live, Vst0),
Vst = branch_state(Fail, Vst1),
- set_type_reg(term, Dst, Vst).
+ set_type_reg(Type, Dst, Vst).
%%
%% Common code for validating bs_skip_utf* instructions.
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 03b52932d1..b3c8c42af7 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -198,9 +198,9 @@ expand_opts(Opts0) ->
%% {debug_info_key,Key} implies debug_info.
Opts = case {proplists:get_value(debug_info_key, Opts0),
proplists:get_value(encrypt_debug_info, Opts0),
- proplists:get_bool(debug_info, Opts0)} of
+ proplists:get_value(debug_info, Opts0)} of
{undefined,undefined,_} -> Opts0;
- {_,_,false} -> [debug_info|Opts0];
+ {_,_,undefined} -> [debug_info|Opts0];
{_,_,_} -> Opts0
end,
foldr(fun expand_opt/2, [], Opts).
@@ -213,14 +213,6 @@ expand_opt(report, Os) ->
[report_errors,report_warnings|Os];
expand_opt(return, Os) ->
[return_errors,return_warnings|Os];
-expand_opt(r12, Os) ->
- [no_recv_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r13, Os) ->
- [no_record_opt,no_recv_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r14, Os) ->
- [no_record_opt,no_line_info,no_utf8_atoms|Os];
-expand_opt(r15, Os) ->
- [no_record_opt,no_utf8_atoms|Os];
expand_opt(r16, Os) ->
[no_record_opt,no_utf8_atoms|Os];
expand_opt(r17, Os) ->
@@ -310,7 +302,7 @@ format_error_reason(Reason) ->
ofile="" :: file:filename(),
module=[] :: module() | [],
core_code=[] :: cerl:c_module() | [],
- abstract_code=[] :: binary() | [], %Abstract code for debugger.
+ abstract_code=[] :: abstract_code(), %Abstract code for debugger.
options=[] :: [option()], %Options for compilation
mod_options=[] :: [option()], %Options for module_info
encoding=none :: none | epp:source_encoding(),
@@ -1323,44 +1315,43 @@ core_inline_module(Code0, #compile{options=Opts}=St) ->
Code = cerl_inline:core_transform(Code0, Opts),
{ok,Code,St}.
-save_abstract_code(Code, #compile{ifile=File}=St) ->
- case abstract_code(Code, St) of
- {ok,Abstr} ->
- {ok,Code,St#compile{abstract_code=Abstr}};
- {error,Es} ->
- {error,St#compile{errors=St#compile.errors ++ [{File,Es}]}}
- end.
+save_abstract_code(Code, St) ->
+ {ok,Code,St#compile{abstract_code=erl_parse:anno_to_term(Code)}}.
+
+debug_info(#compile{module=Module,mod_options=Opts0,ofile=OFile,abstract_code=Abst}) ->
+ AbstOpts = cleanup_compile_options(Opts0),
+ Opts1 = proplists:delete(debug_info, Opts0),
+ {Backend,Metadata,Opts2} =
+ case proplists:get_value(debug_info, Opts0, false) of
+ {OptBackend,OptMetadata} when is_atom(OptBackend) -> {OptBackend,OptMetadata,Opts1};
+ false -> {erl_abstract_code,{none,AbstOpts},Opts1};
+ true -> {erl_abstract_code,{Abst,AbstOpts},[debug_info | Opts1]}
+ end,
+ DebugInfo = erlang:term_to_binary({debug_info_v1,Backend,Metadata}, [compressed]),
-abstract_code(Code0, #compile{options=Opts,ofile=OFile}) ->
- Code = erl_parse:anno_to_term(Code0),
- Abstr = erlang:term_to_binary({raw_abstract_v1,Code}, [compressed]),
- case member(encrypt_debug_info, Opts) of
+ case member(encrypt_debug_info, Opts2) of
true ->
- case keyfind(debug_info_key, 1, Opts) of
- {_,Key} ->
- encrypt_abs_code(Abstr, Key);
+ case lists:keytake(debug_info_key, 1, Opts2) of
+ {value,{_, Key},Opts3} ->
+ encrypt_debug_info(DebugInfo, Key, [{debug_info_key,'********'} | Opts3]);
false ->
- %% Note: #compile.module has not been set yet.
- %% Here is an approximation that should work for
- %% all valid cases.
- Module = list_to_atom(filename:rootname(filename:basename(OFile))),
- Mode = proplists:get_value(crypto_mode, Opts, des3_cbc),
+ Mode = proplists:get_value(crypto_mode, Opts2, des3_cbc),
case beam_lib:get_crypto_key({debug_info, Mode, Module, OFile}) of
error ->
{error, [{none,?MODULE,no_crypto_key}]};
Key ->
- encrypt_abs_code(Abstr, {Mode, Key})
+ encrypt_debug_info(DebugInfo, {Mode, Key}, Opts2)
end
end;
false ->
- {ok,Abstr}
+ {ok,DebugInfo,Opts2}
end.
-encrypt_abs_code(Abstr, Key0) ->
+encrypt_debug_info(DebugInfo, Key, Opts) ->
try
- RealKey = generate_key(Key0),
+ RealKey = generate_key(Key),
case start_crypto() of
- ok -> {ok,encrypt(RealKey, Abstr)};
+ ok -> {ok,encrypt(RealKey, DebugInfo),Opts};
{error,_}=E -> E
end
catch
@@ -1368,6 +1359,18 @@ encrypt_abs_code(Abstr, Key0) ->
{error,[{none,?MODULE,bad_crypto_key}]}
end.
+cleanup_compile_options(Opts) ->
+ lists:filter(fun keep_compile_option/1, Opts).
+
+%% We are storing abstract, not asm or core.
+keep_compile_option(from_asm) -> false;
+keep_compile_option(from_core) -> false;
+%% Parse transform and macros have already been applied.
+keep_compile_option({parse_transform, _}) -> false;
+keep_compile_option({d, _, _}) -> false;
+%% Do not affect compilation result on future calls.
+keep_compile_option(Option) -> effects_code_generation(Option).
+
start_crypto() ->
try crypto:start() of
{error,{already_started,crypto}} -> ok;
@@ -1394,16 +1397,16 @@ encrypt({des3_cbc=Type,Key,IVec,BlockSize}, Bin0) ->
save_core_code(Code, St) ->
{ok,Code,St#compile{core_code=cerl:from_records(Code)}}.
-beam_asm(Code0, #compile{ifile=File,abstract_code=Abst,extra_chunks=ExtraChunks,
- options=CompilerOpts,mod_options=Opts0}=St) ->
- Source = paranoid_absname(File),
- Opts1 = lists:map(fun({debug_info_key,_}) -> {debug_info_key,'********'};
- (Other) -> Other
- end, Opts0),
- Opts2 = [O || O <- Opts1, effects_code_generation(O)],
- Chunks = [{<<"Abst">>, Abst} | ExtraChunks],
- case beam_asm:module(Code0, Chunks, Source, Opts2, CompilerOpts) of
- {ok,Code} -> {ok,Code,St#compile{abstract_code=[]}}
+beam_asm(Code0, #compile{ifile=File,extra_chunks=ExtraChunks,options=CompilerOpts}=St) ->
+ case debug_info(St) of
+ {ok,DebugInfo,Opts0} ->
+ Source = paranoid_absname(File),
+ Opts1 = [O || O <- Opts0, effects_code_generation(O)],
+ Chunks = [{<<"Dbgi">>, DebugInfo} | ExtraChunks],
+ {ok,Code} = beam_asm:module(Code0, Chunks, Source, Opts1, CompilerOpts),
+ {ok,Code,St#compile{abstract_code=[]}};
+ {error,Es} ->
+ {error,St#compile{errors=St#compile.errors ++ [{File,Es}]}}
end.
paranoid_absname(""=File) ->
@@ -1487,15 +1490,17 @@ embed_native_code(Code, {Architecture,NativeCode}) ->
%% errors will be reported).
effects_code_generation(Option) ->
- case Option of
+ case Option of
beam -> false;
report_warnings -> false;
report_errors -> false;
return_errors-> false;
return_warnings-> false;
+ warnings_as_errors -> false;
binary -> false;
verbose -> false;
{cwd,_} -> false;
+ {outdir, _} -> false;
_ -> true
end.
diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl
index d7d5f900de..9f0676538f 100644
--- a/lib/compiler/src/core_scan.erl
+++ b/lib/compiler/src/core_scan.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl
index d60f73d421..bafa9d75b7 100644
--- a/lib/compiler/src/erl_bifs.erl
+++ b/lib/compiler/src/erl_bifs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -81,7 +81,6 @@ is_pure(erlang, float, 1) -> true;
is_pure(erlang, float_to_list, 1) -> true;
is_pure(erlang, float_to_binary, 1) -> true;
is_pure(erlang, floor, 1) -> true;
-is_pure(erlang, hash, 2) -> false;
is_pure(erlang, hd, 1) -> true;
is_pure(erlang, integer_to_binary, 1) -> true;
is_pure(erlang, integer_to_list, 1) -> true;
diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab
index 5e0c2b3ebf..9efb9ad6f8 100755
--- a/lib/compiler/src/genop.tab
+++ b/lib/compiler/src/genop.tab
@@ -538,6 +538,8 @@ BEAM_FORMAT_NUMBER=0
157: has_map_fields/3
158: get_map_elements/3
+# OTP 20
+
## @spec is_tagged_tuple Lbl Reg N Atom
## @doc Test the type of Reg and jumps to Lbl if it is not a tuple.
## Test the arity of Reg and jumps to Lbl if it is not N.
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 8dea7ec03a..ae650546e5 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -184,11 +184,8 @@ form({function,_,_,_,_}=F0, Module, Opts) ->
form({attribute,_,module,Mod}, Module, _Opts) ->
true = is_atom(Mod),
Module#imodule{name=Mod};
-form({attribute,_,file,{File,_Line}}, Module, _Opts) ->
- Module#imodule{file=File};
-form({attribute,_,compile,_}, Module, _Opts) ->
- %% Ignore compilation options.
- Module;
+form({attribute,_,file,{File,_Line}}=F, #imodule{attrs=As}=Module, _Opts) ->
+ Module#imodule{file=File, attrs=[attribute(F)|As]};
form({attribute,_,import,_}, Module, _Opts) ->
%% Ignore. We have no futher use for imports.
Module;
@@ -201,9 +198,8 @@ form(_, Module, _Opts) ->
%% Ignore uninteresting forms such as 'eof'.
Module.
-attribute(Attribute) ->
- Fun = fun(A) -> [erl_anno:location(A)] end,
- {attribute,Line,Name,Val0} = erl_parse:map_anno(Fun, Attribute),
+attribute({attribute,A,Name,Val0}) ->
+ Line = [erl_anno:location(A)],
Val = if
is_list(Val0) -> Val0;
true -> [Val0]
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 4b5d7d919c..004c609311 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -148,6 +148,8 @@ include_attribute(opaque) -> false;
include_attribute(export_type) -> false;
include_attribute(record) -> false;
include_attribute(optional_callbacks) -> false;
+include_attribute(file) -> false;
+include_attribute(compile) -> false;
include_attribute(_) -> true.
function({#c_var{name={F,Arity}=FA},Body}, St0) ->
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index 187e69a22c..716280a95c 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -145,7 +145,7 @@ format_1(#k_local{name=N,arity=A}, Ctxt) ->
"local " ++ format_fa_pair({N,A}, Ctxt);
format_1(#k_remote{mod=M,name=N,arity=A}, _Ctxt) ->
%% This is for our internal translator.
- io_lib:format("remote ~s:~s/~w", [format(M),format(N),A]);
+ io_lib:format("remote ~ts:~ts/~w", [format(M),format(N),A]);
format_1(#k_internal{name=N,arity=A}, Ctxt) ->
"internal " ++ format_fa_pair({N,A}, Ctxt);
format_1(#k_seq{arg=A,body=B}, Ctxt) ->
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 7ca544a537..07dad85c57 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
integers/1,coverage/1,booleans/1,setelement/1,cons/1,
- tuple/1,record_float/1]).
+ tuple/1,record_float/1,binary_float/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -38,7 +38,8 @@ groups() ->
setelement,
cons,
tuple,
- record_float
+ record_float,
+ binary_float
]}].
init_per_suite(Config) ->
@@ -143,6 +144,12 @@ record_float(R, N0) ->
N
end.
+binary_float(_Config) ->
+ <<-1/float>> = binary_negate_float(<<1/float>>),
+ ok.
+
+binary_negate_float(<<Float/float>>) ->
+ <<-Float/float>>.
id(I) ->
I.
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index ff18f8b41c..fd97eea4cb 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -29,7 +29,8 @@
init_per_testcase/2,end_per_testcase/2,
two/1,test1/1,fail/1,float_bin/1,in_guard/1,in_catch/1,
nasty_literals/1,coerce_to_float/1,side_effect/1,
- opt/1,otp_7556/1,float_arith/1,otp_8054/1]).
+ opt/1,otp_7556/1,float_arith/1,otp_8054/1,
+ cover/1]).
-include_lib("common_test/include/ct.hrl").
@@ -45,7 +46,7 @@ groups() ->
[{p,[parallel],
[two,test1,fail,float_bin,in_guard,in_catch,
nasty_literals,side_effect,opt,otp_7556,float_arith,
- otp_8054]}].
+ otp_8054,cover]}].
init_per_suite(Config) ->
@@ -552,3 +553,19 @@ otp_8054_1([H|T], Bin) ->
end,
otp_8054_1(T, Bin);
otp_8054_1([], Bin) -> Bin.
+
+-define(LONG_STRING,
+ "3lz7Q4au2i3DJWNlNhWuzmvA7gYWGXG+LAPtgtlEO2VGSxRqL2WOoHW"
+ "QxORTQfJw17mNEU8i87UKvEPbo9YY8ppiM7vfaG88TTyfEzgUMTgY3I"
+ "vsikMBELPz2AayVz5aaMh9PBFTZ4DkBIFxURBUKHho4Vgt7IzYnWNgn"
+ "3ON5D9VS89TPANK5/PwSUoMQYZ2fk5VLbq7D1ExlnCScvTDnF/WHMQ3"
+ "m2GUcQWb+ajfOf3bnP7EX4f1Q3d/1Soe6lEpf1KN/5S7A/ugjMhy4+H"
+ "Zuo1J1J6CCwEVZ/wDc79OpDPPj/qOGhDK73F8DaMcynZ91El+01vfTn"
+ "uUxNFUHLpuoQ==").
+
+cover(Config) ->
+ %% Cover handling of a huge partially literal string.
+ L = length(Config),
+ Bin = id(<<L:32,?LONG_STRING>>),
+ <<L:32,?LONG_STRING>> = Bin,
+ ok.
diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl
index cd1bc099e9..a4de125d32 100644
--- a/lib/compiler/test/compilation_SUITE.erl
+++ b/lib/compiler/test/compilation_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -319,7 +319,7 @@ self_compile_1(Config, Prefix, Opts) ->
%% Compile the compiler. (In this node to get better coverage.)
CompA = make_compiler_dir(Priv, Prefix++"compiler_a"),
VsnA = Version ++ ".0",
- compile_compiler(compiler_src(), CompA, VsnA, [clint0,clint|Opts]),
+ compile_compiler(compiler_src(), CompA, VsnA, Opts),
%% Compile the compiler again using the newly compiled compiler.
%% (In another node because reloading the compiler would disturb cover.)
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 474c3e2ca0..f5e904a50a 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,14 +27,16 @@
-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,appup_test/1,
+ debug_info/4, custom_debug_info/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, kernel_listing/1, encrypted_abstr/1,
- strict_record/1, utf8_atoms/1, extra_chunks/1,
- cover/1, env/1, core/1,
+ strict_record/1, utf8_atoms/1, utf8_functions/1, extra_chunks/1,
+ cover/1, env/1, core_pp/1,
core_roundtrip/1, asm/1, optimized_guards/1,
sys_pre_attributes/1, dialyzer/1,
- warnings/1, pre_load_check/1, env_compiler_options/1
+ warnings/1, pre_load_check/1, env_compiler_options/1,
+ bc_options/1
]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -48,10 +50,10 @@ all() ->
[app_test, appup_test, file_1, forms_2, module_mismatch, big_file, outdir,
binary, makedep, cond_and_ifdef, listings, listings_big,
other_output, kernel_listing, encrypted_abstr,
- strict_record, utf8_atoms, extra_chunks,
- cover, env, core, core_roundtrip, asm, optimized_guards,
+ strict_record, utf8_atoms, utf8_functions, extra_chunks,
+ cover, env, core_pp, core_roundtrip, asm, optimized_guards,
sys_pre_attributes, dialyzer, warnings, pre_load_check,
- env_compiler_options].
+ env_compiler_options, custom_debug_info, bc_options].
groups() ->
[].
@@ -504,17 +506,23 @@ encrypted_abstr_1(Simple, Target) ->
{ok,simple} = compile:file(Simple,
[debug_info,{debug_info_key,Key},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
{ok,simple} = compile:file(Simple,
[{debug_info_key,Key},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
{ok,simple} = compile:file(Simple,
[debug_info,{debug_info_key,{des3_cbc,Key}},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
+
+ {ok,simple} = compile:file(Simple,
+ [{debug_info,{?MODULE,ok}},
+ {debug_info_key,Key},
+ {outdir,TargetDir}]),
+ verify_abstract(Target, ?MODULE),
{ok,{simple,[{compile_info,CInfo}]}} =
beam_lib:chunks(Target, [compile_info]),
@@ -539,7 +547,7 @@ encrypted_abstr_1(Simple, Target) ->
NewKey = "better use another key here",
write_crypt_file(["[{debug_info,des3_cbc,simple,\"",NewKey,"\"}].\n"]),
{ok,simple} = compile:file(Simple, [encrypt_debug_info,report]),
- verify_abstract("simple.beam"),
+ verify_abstract("simple.beam", erl_abstract_code),
ok = file:delete(".erlang.crypt"),
beam_lib:clear_crypto_key_fun(),
{error,beam_lib,{key_missing_or_invalid,"simple.beam",abstract_code}} =
@@ -572,9 +580,10 @@ encrypted_abstr_no_crypto(Simple, Target) ->
{outdir,TargetDir},report]),
ok.
-verify_abstract(Target) ->
- {ok,{simple,[Chunk]}} = beam_lib:chunks(Target, [abstract_code]),
- {abstract_code,{raw_abstract_v1,_}} = Chunk.
+verify_abstract(Beam, Backend) ->
+ {ok,{simple,[Abst, Dbgi]}} = beam_lib:chunks(Beam, [abstract_code, debug_info]),
+ {abstract_code,{raw_abstract_v1,_}} = Abst,
+ {debug_info,{debug_info_v1,Backend,_}} = Dbgi.
has_crypto() ->
try
@@ -593,6 +602,26 @@ install_crypto_key(Key) ->
ok = beam_lib:crypto_key_fun(F).
%% Miscellanous tests, mainly to get better coverage.
+debug_info(erlang_v1, Module, ok, _Opts) ->
+ {ok, [Module]};
+debug_info(erlang_v1, _Module, error, _Opts) ->
+ {error, unknown_format}.
+
+custom_debug_info(Config) when is_list(Config) ->
+ {Simple,_} = get_files(Config, simple, "file_1"),
+
+ {ok,simple,OkBin} = compile:file(Simple, [binary, {debug_info,{?MODULE,ok}}]), %Coverage
+ {ok,{simple,[{abstract_code,{raw_abstract_v1,[simple]}}]}} =
+ beam_lib:chunks(OkBin, [abstract_code]),
+ {ok,{simple,[{debug_info,{debug_info_v1,?MODULE,ok}}]}} =
+ beam_lib:chunks(OkBin, [debug_info]),
+
+ {ok,simple,ErrorBin} = compile:file(Simple, [binary, {debug_info,{?MODULE,error}}]), %Coverage
+ {ok,{simple,[{abstract_code,no_abstract_code}]}} =
+ beam_lib:chunks(ErrorBin, [abstract_code]),
+ {ok,{simple,[{debug_info,{debug_info_v1,?MODULE,error}}]}} =
+ beam_lib:chunks(ErrorBin, [debug_info]).
+
cover(Config) when is_list(Config) ->
io:format("~p\n", [compile:options()]),
ok.
@@ -699,6 +728,23 @@ utf8_atoms(Config) when is_list(Config) ->
NoUtf8AtomForms = [{attribute,Anno,module,no_utf8_atom}|Forms],
error = compile:forms(NoUtf8AtomForms, [binary, r19]).
+utf8_functions(Config) when is_list(Config) ->
+ Anno = erl_anno:new(1),
+ Atom = binary_to_atom(<<"こんにちは"/utf8>>, utf8),
+ Forms = [{attribute,Anno,compile,[export_all]},
+ {function,Anno,Atom,0,[{clause,Anno,[],[],[{atom,Anno,world}]}]}],
+
+ Utf8FunctionForms = [{attribute,Anno,module,utf8_function}|Forms],
+ {ok,utf8_function,Utf8FunctionBin} =
+ compile:forms(Utf8FunctionForms, [binary]),
+ {ok,{utf8_function,[{atoms,_}]}} =
+ beam_lib:chunks(Utf8FunctionBin, [atoms]),
+ code:load_binary(utf8_function, "compile_SUITE", Utf8FunctionBin),
+ world = utf8_function:Atom(),
+
+ NoUtf8FunctionForms = [{attribute,Anno,module,no_utf8_function}|Forms],
+ error = compile:forms(NoUtf8FunctionForms, [binary, r19]).
+
extra_chunks(Config) when is_list(Config) ->
Anno = erl_anno:new(1),
Forms = [{attribute,Anno,module,extra_chunks}],
@@ -749,9 +795,9 @@ env_1(Simple, Target) ->
%% Test pretty-printing in Core Erlang format and then try to
%% compile the generated Core Erlang files.
-core(Config) when is_list(Config) ->
+core_pp(Config) when is_list(Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
- Outdir = filename:join(PrivDir, "core"),
+ Outdir = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME)),
ok = file:make_dir(Outdir),
TestBeams = get_unique_beam_files(),
@@ -759,11 +805,11 @@ core(Config) when is_list(Config) ->
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
{Mod,Abstr} end || Beam <- TestBeams],
- test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr).
+ test_lib:p_run(fun(F) -> do_core_pp(F, Outdir) end, Abstr).
-do_core({M,A}, Outdir) ->
+do_core_pp({M,A}, Outdir) ->
try
- do_core_1(M, A, Outdir)
+ do_core_pp_1(M, A, Outdir)
catch
throw:{error,Error} ->
io:format("*** compilation failure '~p' for module ~s\n",
@@ -775,7 +821,7 @@ do_core({M,A}, Outdir) ->
error
end.
-do_core_1(M, A, Outdir) ->
+do_core_pp_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),
@@ -1319,6 +1365,47 @@ env_compiler_options(_Config) ->
end,
lists:foreach(F, Cases).
+%% Test options for compatibility with previous major versions of OTP.
+
+bc_options(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+
+ 101 = highest_opcode(DataDir, small_float, [no_line_info]),
+
+ 103 = highest_opcode(DataDir, big,
+ [no_record_opt,no_line_info,no_stack_trimming]),
+
+ 125 = highest_opcode(DataDir, small_float, [no_line_info,no_float_opt]),
+
+ 132 = highest_opcode(DataDir, small,
+ [no_record_opt,no_float_opt,no_line_info]),
+
+ 136 = highest_opcode(DataDir, big, [no_record_opt,no_line_info]),
+
+ 153 = highest_opcode(DataDir, big, [no_record_opt]),
+ 153 = highest_opcode(DataDir, big, [r16]),
+ 153 = highest_opcode(DataDir, big, [r17]),
+ 153 = highest_opcode(DataDir, big, [r18]),
+ 153 = highest_opcode(DataDir, big, [r19]),
+ 153 = highest_opcode(DataDir, small_float, [r16]),
+ 153 = highest_opcode(DataDir, small_float, []),
+
+ 158 = highest_opcode(DataDir, small_maps, [r17]),
+ 158 = highest_opcode(DataDir, small_maps, [r18]),
+ 158 = highest_opcode(DataDir, small_maps, [r19]),
+ 158 = highest_opcode(DataDir, small_maps, []),
+
+ 159 = highest_opcode(DataDir, big, []),
+
+ ok.
+
+highest_opcode(DataDir, Mod, Opt) ->
+ Src = filename:join(DataDir, atom_to_list(Mod)++".erl"),
+ {ok,Mod,Beam} = compile:file(Src, [binary|Opt]),
+ {ok,{Mod,[{"Code",Code}]}} = beam_lib:chunks(Beam, ["Code"]),
+ <<16:32,0:32,HighestOpcode:32,_/binary>> = Code,
+ HighestOpcode.
+
%%%
%%% Utilities.
%%%
diff --git a/lib/compiler/test/compile_SUITE_data/small_float.erl b/lib/compiler/test/compile_SUITE_data/small_float.erl
new file mode 100644
index 0000000000..5cbb5aef83
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/small_float.erl
@@ -0,0 +1,5 @@
+-module(small_float).
+-export([f/1]).
+
+f(F) when is_float(F) ->
+ F / 2.
diff --git a/lib/compiler/test/compiler.cover b/lib/compiler/test/compiler.cover
index 2be079944f..3fd7fc1937 100644
--- a/lib/compiler/test/compiler.cover
+++ b/lib/compiler/test/compiler.cover
@@ -1,5 +1,5 @@
{incl_app,compiler,details}.
%% -*- erlang -*-
-{excl_mods,compiler,[core_scan,core_parse,sys_pre_expand]}.
+{excl_mods,compiler,[core_scan,core_parse]}.
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 76dfaee482..9ad417b09b 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index fa6d5ee957..01b064cc10 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.