aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
AgeCommit message (Collapse)Author
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
2016-04-14v3_kernel: Construct literal lists properlyBjörn Gustavsson
Use cerl:make_list/1 instead of a home-made make_list/1 to ensure that literal lists are constructed as literals. In a future release, we would like to forbid in the loader construction of literal lists using instructions like: put_list {atom,a} [] Dst The proper way is: move {literal,[a]} {x,0} Also update the comment about "put_list Const [] Dst" in ops.tab.
2016-04-14Use the register map in %live in beam_utils:is_killed_block/2Björn Gustavsson
In 1f0ae04d374, a complete register map was introduced in the %live instructions thar are added by beam_utils:live_opt/1. Use the register map to improve beam_utils:is_killed_block/2.
2016-04-13Merge branch 'henrik/update-copyrightyear'Henrik Nord
* henrik/update-copyrightyear: update copyright-year
2016-04-11Teach beam_utils to check liveness for put_map instructionsBjörn Gustavsson
2016-04-11beam_peep: Help out beam_jumpBjörn Gustavsson
beam_jump fails to optimize the following: jump 2 label 1 label 2 Since this situation is rare, instead of complicating beam_jump, add the optimization to beam_peep. It will always succeed, since adjacent labels have been coalesced.
2016-04-08Remove unreachable code after 'raise' instructionsBjörn Gustavsson
Remove the unreachable instructions after a 'raise' instruction (e.g. a 'jump' or 'deallocate', 'return') to decrease code size.
2016-03-24Fix compile:forms/1,2 crash when not in an existing directoryBjörn Gustavsson
compile:forms/1,2 will crash when the current working directory has been deleted. Fix that problem, and while we are at it, also stop including {source,""} in module_info() when no source code file is given. Reported-at: http://bugs.erlang.org/browse/ERL-113 Reported-by: Adam Lindberg
2016-03-17compile: Pre-load compiler modules when invoked from 'erlc'Björn Gustavsson
Slightly speed up 'erlc' by pre-loading the modules used by the compiler. Write a test case to ensure that the correct set of modules are loaded.
2016-03-15update copyright-yearHenrik Nord
2016-03-10beam_block: Eliminate unsafe optimizationBjörn Gustavsson
Consider this code: %% Start of block get_tuple_element Tuple 0 Element get_map_elements Fail Map [Key => Dest] . . . move Element UltimateDest %% End of block Fail: %% Code that uses Element. beam_block (more precisely, otp_tuple_element/1) would incorrectly transform the code to this: %% Start of block get_map_elements Fail Map [Key => Dest] . . . get_tuple_element Tuple 0 UltimateDest %% End of block Fail: %% Code that uses Element. That is, the code at label Fail would use register Element, which is either uninitalized or contains the wrong value. We could fix this problem by always keeping label information at hand when optimizing blocks so that we could check the code at the failure label for get_map_elements. That would require changes to beam_block and beam_utils. We might consider doing that in the future if it turns out be worth it. For now, I have decided that I want to keep the simplicity of blocks (allowing them to be optimized without keeping label information). That could be achieved by not including get_map_elements in blocks. Another way, which I have chosen, is to only allow get_map_elements as the first instruction in the block. For background on the bug: c288ab8 introduced the beam_reorder pass and 5f431276 introduced opt_tuple_element() in beam_block.
2016-03-01Generalize bit string comprehensionsBjörn Gustavsson
The expression in a bit string comprehension is limited to a literal bit string expression. That is, the following code is legal: << <<X>> || X <- List >> but not this code: << foo(X) || X <- List >> The limitation is annoying. For one thing, tools that transform the abstract format must be careful not to produce code such as: << begin %% Some instrumentation code. <<X>> end || X <- List >> One reason for the limitation could be that we'll get reduce/reduce conflicts if we try to allow an arbitrary expression in a bit string comprehension: binary_comprehension -> '<<' expr '||' lc_exprs '>>' : {bc,?anno('$1'),'$2','$4'}. Unfortunately, there does not seem to be an easy way to work around that problem. The best we can do is to allow 'expr_max' expressions (as in the binary syntax): binary_comprehension -> '<<' expr_max '||' lc_exprs '>>' : {bc,?anno('$1'),'$2','$4'}. That will work, but functions calls must be enclosed in parentheses: << (foo(X)) || X <- List >>
2016-02-25Produce warnings for binary patterns that will never matchBjörn Gustavsson
Binary matching can be confusing. For example: 1> <<-1>> = <<-1>>. ** exception error: no match of right hand side value <<"ÿ">> 2> When constructing binaries, the value will be masked to fit in the binary segment. But no such masking happens when matching binaries. One solution that we considered was to do the same masking when matching. We have rejected that solution for several reasons: * Masking in construction is highly controversial and by some people considered a bad design decision. * While masking of unsigned numbers can be understood, masking of signed numbers it not easy to understand. * Then there is the question of backward compatibility. Adding masking to matching would mean that clauses that did not match earlier would start to match. That means that code that has never been tested will be executed. Code that has not been tested will usually not work. Therefore, we have decided to warn for binary patterns that cannot possibly match. While we are it, we will also warn for the following example where size for a binary segment is invalid: bad_size(Bin) -> BadSize = bad_size, <<42:BadSize>> = Bin. That example would crash the HiPE compiler because the BEAM compiler would generate a bs_get_integer2 instruction with an invalid size field. We can avoid that crash if sys_core_fold not only warns for bad binary pattern, but also removes the clauses that will not match. Reported-by: http://bugs.erlang.org/browse/ERL-44 Reported-by: Kostis Sagonas
2016-02-23v3_core: Include line number annotations in binary patternsBjörn Gustavsson
We will need them when we start to produce warnings for patterns that can't match.
2016-02-23sys_core_fold: Introduce var_list/2Björn Gustavsson
As a preparation for checking binary patterns we will add var_list/2 that will work as pattern_list/2 but is guaranteed not to throw an exception. That way, we will only have to use try...catch for the few remaining calls to pattern_list/2.
2016-02-23sys_core_fold: Optimize clause/4Björn Gustavsson
Save work the *extremely* common case that the guard is a literal.
2016-02-17compiler: Update the compiler to handle typed record fieldsBjörn Gustavsson
2016-02-10Merge branch 'maint'Björn Gustavsson
* maint: Eliminate crash because of unsafe delaying of sub-binary creation
2016-02-08Eliminate crash because of unsafe delaying of sub-binary creationBjörn Gustavsson
The following code would fail to compile: decode(<<Code/integer, Bin/binary>>) -> <<C1/integer, B1/binary>> = Bin, case C1 of X when X =:= 1 orelse X =:= 2 -> Bin2 = <<>>; _ -> Bin2 = B1 end, case Code of 1 -> decode(Bin2); _ -> Bin2 end. The error message would be: t: function decode/1+28: Internal consistency check failed - please report this bug. Instruction: return Error: {match_context,{x,0}}: The beam_bsm pass would delay the creation of a sub-binary when it was unsafe to do so. The culprit was the btb_follow_branch/3 function that for performance reasons cached labels that had already been checked. The problem was the safety of a label also depends on the contents of the registers. Therefore, the key for caching needs to be both the label and the register contents. Reported-by: José Valim
2016-02-03v3_core: Eliminate double processing of patternsBjörn Gustavsson
Internally in the v3_core pass, an #imatch{} record represents a match expression: Pattern = Expression If Pattern is a single, unbound variable, #imatch{} will be rewritten to #iset{}; otherwise it will be rewritten to #icase{}. To determine how #imatch{} should be translated, the pattern is processed using upattern/3. The return value from upattern/3 is thrown away (after having been used for determing how the #imatch{} record should be translated). That means that every pattern in an #imatch{} is processed twice, which is wasteful. We can easily avoid the double processing of patterns by introducing a new helper function that determines whether the pattern is a new variable.
2016-01-28Extend cerl_trees:mapfold with a 'pre-order' operationStavros Aronis
When manipulating Core Erlang trees it may be useful to perform some operation when a node is visited, before inspecting children nodes. The definition of cerl_tree:mapfold/3 does not allow that, as it applies the given function only after all the recursive calls on the children nodes have been completed. This patch adds a new argument to mapfold: a function that is applied when a node is first entered. As an example of its use, consider the case where one wants to move a 'call' node earlier, by adding 'let' node and replacing the 'call' node with the defined variable. The name of that variable must be specified before one traverses the inner tree (especially if such replacements can be nested).
2016-01-20compiler: Improve type and specsHans Bolinder
2016-01-18Merge branch 'maint'Björn-Egil Dahlberg
2016-01-14compiler, hipe: Fix pretty printing of Core MapsBjörn-Egil Dahlberg
Literal maps could cause dialyzer to crash when pretty printing the results. Reported-by: Chris McGrath <[email protected]>
2016-01-13Merge branch 'maint'Björn Gustavsson
* maint: Fix crash when attempting to update a fun as if it were a map
2016-01-12Fix crash when attempting to update a fun as if it were a mapBjörn Gustavsson
The following example would cause an internal consistency failure in the compiler: f() -> ok. update() -> (fun f/0)#{u => 42}. The reason is that internally, v3_core will (incorrectly) rewrite update/0 to code similar to this: update() -> if is_map(fun f/0) -> maps:update(u, 42, fun f/0) end. Since funs are not allowed to be created in guards, incorrect and unsafe code would be generated. It is easy to fix the bug. There already is a is_valid_map_src/1 function in v3_core that tests whether the argument for the map update operation can possibly be a valid map. A fun is represented as a variable with a special name in Core Erlang, so it would not be recognized as unsafe. All we'll need to do to fix the bug is to look closer at variables to ensure they don't represent funs. That will ensure that the code is rewritten in the correct way: update() -> error({badmap,fun f/0}) end. Reported-by: Thomas Arts
2016-01-11Merge branch 'maint'Björn Gustavsson
* maint: Eliminate crash in v3_codegen