aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
AgeCommit message (Collapse)Author
2016-05-30beam_validator: Add is_bitstring/1 as a safe BIFBjörn Gustavsson
beam_validator wrongly complained that the following was not safe because it didn't know that is_bitstring/1 is safe: food(Curriculum) -> [try is_bitstring(functions) catch _ -> 0 end, Curriculum]. While we are it, also add a new bif_SUITE test suite to cover some more code in beam_validator.
2016-05-30beam_validator: Remove uncovered lineBjörn Gustavsson
The raise/3 instruction is specially handled, thus there is no need for bif_type/3 to handle raise/3 (also, the number of arguments was incorrect, so it could never have matched).
2016-05-30Teach beam_utils:is_pure_test/1 to handle is_bitstr and is_function2Björn Gustavsson
The 'is_bitstr' and 'is_function2' tests are pure. The corresponding BIFs have different names; thus the default call to erl_internal:new_type_test/2 is not sufficient.
2016-05-25beam_utils: Simplify handling of 'return' to eliminate uncovered lineBjörn Gustavsson
Y registers are killed by the deallocate/1 instruction, so there is no need to handle Y register in the return/1 instruction in check_liveness/3. There is also no need to keep check_liveness_live_ret/3 since it is only used in one place.
2016-05-25beam_jump: Clean up handling of labels before func_infoBjörn Gustavsson
In complicated code with many indirect jumps to the func_info label, a label could get lost.
2016-05-25beam_expect: Correctly handle blocks with multiple allocsBjörn Gustavsson
A negative allocation could be calculated if a block had multiple allocations. Make sure to process the block in the right order so that the correct allocation is processed. Also add an assertion. This bug was often not noticed because beam_type usually silently recalculates the allocation amount in test_heap/2 instructions.
2016-05-25v3_codegen: Don't confuse beam_validatorBjörn Gustavsson
Generate code that not only is safe, but can easily be seen by beam_validator to be safe.
2016-05-25v3_codegen: Correct code generation for an error/1 call in a guardBjörn Gustavsson
Sometimes v3_codegen would generate unsafe code when there was a call to error/1 in a guard.
2016-05-25beam_receive: Don't crash when encountering nonsensical codeBjörn Gustavsson
2016-05-23Merge branch 'bjorn/compiler/misc'Björn Gustavsson
* bjorn/compiler/misc: beam_bool_SUITE: Cover one more line beam_utils_SUITE: Cover more lines in beam_utils beam_reorder: Don't confuse beam_validator beam_bool: Reject potentially unsafe optimization v3_core: Don't depend on sys_core_fold for cleaning up beam_type: Eliminate crash beam_type: Correct handling of setelement/3 beam_validator: Handle cons literals better beam_validator: Keep better track of tuple literals
2016-05-23beam_reorder: Don't confuse beam_validatorBjörn Gustavsson
Make sure we don't optimize code such as: is_tuple Fail Src test_arity Fail Src Arity get_tuple_element Src Pos Dst is_map Fail Src If we would reorder the instructions like this: is_tuple Fail Src test_arity Fail Src Arity is_map Fail Src get_tuple_element Src Pos Dst beam_validator would complain that the type for Src is a map instead of a tuple. Since the code has problems to begin with, there is no need to do the optimization.
2016-05-23beam_bool: Reject potentially unsafe optimizationBjörn Gustavsson
When calculating the sets of registers that must be killed or unused, registers set in a {protected,_,_,_} block were not considered. That could result in a crash in the assertion in beam_utils:live_opt_block/4.
2016-05-23v3_core: Don't depend on sys_core_fold for cleaning upBjörn Gustavsson
a3ec2644f5 attempted to teach v3_core not to generate code with unbound variables. The approach taken in that commit is to discard all expressions following a badmatch. That does not work if the badmatch is nested: {[V] = [] = foo,V}, V That would be rewritten to: {error({badmatch,foo})}, V where V is unbound. If we were to follow the same approach, the tuple construction code would have to look out for a badmatch. As would list construction, begin...end, and so on. Therefore, as it is impractical to discard all expressions that follow a badmatch, the only other solution is to ensure that the variables that the pattern binds will somehow be bound. That can be arranged by rewriting the pattern to a pattern that binds the same variables. Thus: error({badmatch,foo}), E = foo, case E of {[V],[]} -> V; Other -> error({badmatch,Other} end
2016-05-23beam_type: Eliminate crashBjörn Gustavsson
The following code: simple() -> case try 0 after [] end of 0 -> college; 1 -> 0 end. would crash the compiler like this: crash reason: {case_clause, {'EXIT', {function_clause, [{beam_type,simplify_select_val_int, [{select,select_val, {x,0}, {f,7}, [{integer,1},{f,9},{integer,0},{f,8}]}, 0], [{file,"beam_type.erl"},{line,169}]}, {beam_type,simplify_basic_1,3, [{file,"beam_type.erl"},{line,155}]}, {beam_type,opt,3,[{file,"beam_type.erl"},{line,57}]}, {beam_type,function,1,[{file,"beam_type.erl"},{line,36}]}, {beam_type,'-module/2-lc$^0/1-0-',1, [{file,"beam_type.erl"},{line,30}]}, {beam_type,module,2,[{file,"beam_type.erl"},{line,30}]}, {compile,'-select_passes/2-anonymous-2-',2, [{file,"compile.erl"},{line,521}]}, {compile,'-internal_comp/4-anonymous-1-',2, [{file,"compile.erl"},{line,306}]}]}}} The root cause is that the type representation is not well-defined. Integers could be represented in three different ways: integer {integer,{1,10}} {integer,0} However, only the first two forms were handled. To avoid similar problems in the future: * Make the type representation stricter. Make sure that integers are only represented as 'integer' or {integer,{Min,Max}}. * Call verify_type/1 whenever a new type is added (not only when merging types) to ensure that only the supported types are added to the type database). (ERL-150)
2016-05-20beam_type: Correct handling of setelement/3Björn Gustavsson
We must be careful how we treat the type info for the result of: setelement(Index, Tuple, NewValue) If Tuple had type information, the result of setelement/3 (in x(0)) would be assigned the same type information. But that is not safe for: setelement(1, Tuple, NewValue) since the type for the first element will be changed. Therefore, we must take care to remove the type information for the first element of the tuple if might have been modified by setelement/3.
2016-05-20beam_validator: Handle cons literals betterBjörn Gustavsson
As a preparation for better optimizations in beam_type, a list literal must be accepted as a 'cons'.
2016-05-20beam_validator: Keep better track of tuple literalsBjörn Gustavsson
As a preparation for upcoming better optimizations in beam_type, we will need to keep better track of tuple literals so that beam_validator will not falsely reject safe code.
2016-05-18Use arity() consistentlyKostis Sagonas
Specs of various *_arity functions in this module used different types (integer(), non_neg_integer(), byte()) to refer to the type arity().
2016-05-16Merge branch 'bjorn/compiler/beam_bool/ERL-143'Björn Gustavsson
* bjorn/compiler/beam_bool/ERL-143: Eliminate crash in beam_bool Add beam_bool_SUITE Add missing test cases in andor_SUITE and beam_block_SUITE
2016-05-16Eliminate crash in beam_boolBjörn Gustavsson
beam_bool would crash when attempting to optimize BEAM code similar to this code: bif '=:=' Reg1 SomeValue => y(0) bif '=:=' Reg2 {atom,true} => x(2) bif '=:=' Reg3 {atom,true} => x(3) bif 'or' x(2) x(3) => x(2) is_eq_exact Fail x(2) {atom,true} The problem is that the first instruction that assigns a value to a Y register. beam_bool:ssa_assign/2 will not accept a Y register argument. We could change ssa_assign/2 to accept a Y register, but that would only cause the entire optimization to be rejected later because the Y register is alive in the code that follows. Therefore, a better solution is to modify extend_block/3 so that the instruction that assign to Y registers are not added to the block. That is, the optimizer will only operate on the following code: bif '=:=' Reg2 {atom,true} => x(2) bif '=:=' Reg3 {atom,true} => x(3) bif 'or' x(2) x(3) => x(2) is_eq_exact Fail x(2) {atom,true} Usually the optimization will succeed, rewriting the four instructions to a select_val instruction. Assembly code such as the above can be produced by code similar to: Y = Something == SomethingElse, case Y of Condition; OtherCondition -> . . . end, . . ., Y. Reported-by: http://bugs.erlang.org/browse/ERL-143 Reported-by: José Valim
2016-05-13beam_utils: Correct break in conventions for split_even/1 and join_even/1Björn Gustavsson
Exported functions in this file should appear at the top of the file. Also add missing spaces after commas.
2016-05-13beam_utils: Remove clause checking for illegal set/4 instructionBjörn Gustavsson
I can't remember that clause ever trigger during development. Remove it to eliminated an uncovered line.
2016-05-13beam_utils: Simplify the return value for check_liveness/3Björn Gustavsson
check_liveness/3 returns {unknown,State} if an instruction is not handled. All callers will handle 'unknown' the same way as 'used'. Therefore, we can simplify the code and improve the coverage if we return {used,State} instead of {unknown,State}.
2016-05-13beam_utils: Remove unused codeBjörn Gustavsson
2016-05-13beam_utils: Let code_at/2 fail if the label does not existBjörn Gustavsson
All callers only calls code_at/2 for existing labels and they don't handle the return value 'none'.
2016-05-13beam_utils: Remove unused handling of try/3 in live_opt/4Björn Gustavsson
30cc5c902d moved try/3 instruction inside blocks, so the clause for handling try/3 in live_opt/4 is never executed.
2016-05-13beam_utils: Correct translation of BIFs to testsBjörn Gustavsson
Two lines were never covered, because '[]' was used instead of 'nil'.
2016-05-13core_pp: Remove uncovered clause in is_simple_term/1Björn Gustavsson
The clause for handling #c_values{} in is_simple_term/1 is never executed. It can be safely removed, since there is a default clause that will return 'false' in the extremly unlikely event that a Without the clause, code such as: let <_v1,_v2> = <1,2> in {_v1,_v2} would be printed with an extra newline: let <_v1,_v2> = <1,2> in {_v1,_v2}
2016-05-13core_pp: Crash on unhandled Core Erlang formsBjörn Gustavsson
Don't try to be nice. Since we now have good test suites for Core Erlang, just let it crash.
2016-05-13core_pp: Remove unused clauses in unindent/3 to improve coverageBjörn Gustavsson
2016-05-13core_pp: Remove useless try...catchBjörn Gustavsson
We will get more information if we don't catch the exception.
2016-05-13core_pp: Simplify printing of map literalsBjörn Gustavsson
Map patterns are never represented as literals. Therefore, a map literal should always be printed with the 'assoc' operator. That also means that there is no remaining use of the 'class' field and that it can be removed from the 'ctxt' record.
2016-05-12sys_core_fold: Don't generated failing calls such as 3(4)Björn Gustavsson
Rewrite code such as: X = not_a_fun, X() to: error({badfun,not_a_fun}) Also generate a warning.
2016-05-09compiler: Let module_info(attributes) skip more attributesHans Bolinder
'callback' and 'optional_callbacks' are no longer wild attributes.
2016-04-29Merge branch 'bjorn/compiler/core-erlang-fixes'Björn Gustavsson
* bjorn/compiler/core-erlang-fixes: Slightly optimize core_pp v3_core: Don't depend on sys_core_fold for cleaning up
2016-04-28dialyzer: Unfold cerl patterns containing mapsMagnus Lång
Dialyzer relies heavily on the assumption that the type of a literal that is used as a pattern is the type of any value that can match that pattern. For maps, that is not true, and it was causing bad analysis results. A new help function dialyzer_utils:refold_pattern/1 identifies maps in literal patterns, and unfolds and labels them, allowing them to be properly analysed.
2016-04-28Slightly optimize core_ppBjörn Gustavsson
2016-04-28v3_core: Don't depend on sys_core_fold for cleaning upBjörn Gustavsson
v3_core would generate unsafe code for the following example: f() -> {ok={error,E}} = foo(), E. Internally, the code would look similar to: f() -> Var = foo(), error({badmatch,Var}), E. That is, there would remain a reference to an unbound variable. Normally, sys_core_fold would remove the reference to 'E', but if if optimization was disabled the compiler would crash.
2016-04-25compiler: Remove use of crypto:rand_bytes/1Ingela Anderton Andin
Use case in compile.erl is cryptographical so use crypto:strong_rand_bytes/1 instead. Use case in test suite is not cryptographical so use other test instead.
2016-04-25Merge branch 'bjorn/compiler/remove-timestamps/OTP-13504'Björn Gustavsson
* bjorn/compiler/remove-timestamps/OTP-13504: Remove timestamps from BEAM files
2016-04-25Remove timestamps from BEAM filesBjörn Gustavsson
As long as anyone can remember, the compilation time has been included in BEAM files (and can be retrieved using Mod:module_info(compile)). The timestamp has caused problems for anyone using tools such as 'cmp' to compare BEAM files or for package managers: http://erlang.org/pipermail/erlang-questions/2016-April/088717.html Rarely has the timestamp been of any use. Yes, sometimes the timestamp could help to figuring out which version of a module was used, but nowadays a better way is to use Mod:module_info(md5). To get rid of this problem, remove the timestamp from BEAM files in OTP 19. Don't add an option to include timestamps. Utilities that depend on the timestamp will need to be modified. For example: http://erlang.org/pipermail/erlang-questions/2016-April/088730.html Instead of using the compilation time, the MD5 for the BEAM code can be used. Example: 1> c:module_info(md5). <<79,26,188,243,168,60,58,45,34,69,19,222,138,190,214,118>> 2> beam_lib:md5(code:which(c)). {ok,{c,<<79,26,188,243,168,60,58,45,34,69,19,222,138,190,214,118>>}} 3>
2016-04-21v3_core: Construct {badmap,Map} as literal if possibleBjörn Gustavsson
2016-04-21core_pp: Print {file,File} annotations more compactlyBjörn Gustavsson
This will speed up test cases that print all annotations.
2016-04-21core_pp: Add format_all/1 that prints all annotationsBjörn Gustavsson
2016-04-21core_parse: Don't sort map patternsBjörn Gustavsson
If we pretty print to a file and read it back in, we expect to get the same cerl data structures back.
2016-04-21core_parse: Handle annotations in more contextsBjörn Gustavsson
Annotations would not be accepted for all constructs.
2016-04-21cerl_trees: Correct handling of maps in label/2Björn Gustavsson
Make sure that we don't convert a map pattern to a map expression.
2016-04-21cerl: Add missing API function is_c_map_pattern/1Björn Gustavsson
2016-04-20Eliminate Dialyzer warnings for unmatched returnsBjörn Gustavsson
2016-04-18Merge branch 'bjorn/compiler/misc-opt'Björn Gustavsson
* bjorn/compiler/misc-opt: v3_kernel: Construct literal lists properly Use the register map in %live in beam_utils:is_killed_block/2 Teach beam_utils to check liveness for put_map instructions beam_peep: Help out beam_jump