aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_validator.erl
AgeCommit message (Collapse)Author
2018-02-09Check that the stack is initialized when an exception may occurBjörn Gustavsson
Strengthen beam_validator to check that the stack is initialized when an instruction with an {f,0} operand is executed. For example, the following code sequence: {allocate,0,1}. {bif,element,{f,0},[{integer,1},{x,0}],{x,0}}. should not be accepted because the stack may be scanned if element/2 fails. That could cause a crash or other undefined behavior if garbage on the stack looks like a catch tag.
2018-01-08beam_validator: Strengthen validation of GC instructionsBjörn Gustavsson
beam_validator did not verify that the Y registers were initialized before executing the following instructions that could cause a GC: bs_append/8 bs_init2/6 bs_init_bits/6 gc_bif1/5 gc_bif2/6 gc_bif3/7 test_heap/2 That means that, for example, an incorrect optimization that replaced an 'allocate_zero' instruction with an 'allocate' instruction when it was not safe, would not be rejected by beam_validtor, but would instead cause a crash or other undefined behavior at runtime. Also fix a minor bug in beam_type exposed by the stronger checking. When compiling from .S files, beam_type did not handle the init/1 instruction and could produce unsafe code.
2017-09-29Fix incorrect internal consistency failure for binary matching codeBjörn Gustavsson
4c31fd0b9665 made the merging of match contexts stricter; in fact, a little bit too strict. Two match contexts with different number of slots would be downgraded to the 'term' type. The correct way is to keep the match context but set the number of slots to the lowest number of slots of the two match contexts. https://bugs.erlang.org/browse/ERL-490
2017-08-30Make handling of match contexts stricterBjörn Gustavsson
beam_validator could fail issue a diagnostic when a register that was supposed to be a match context was not guaranteed to be a match context. The bug was in merging of types. Merging of a match context with another term would result in a match context. That is wrong. Merging should produce a more general type, not a narrower type. Also, the valid slots in two match contexts should be combined with 'band', not 'bor'.
2017-08-22Merge branch ↵Lukas Larsson
'john/compiler/fail-labels-in-blocks-otp-18/ERIERL-48/OTP-14522' into maint * john/compiler/fail-labels-in-blocks-otp-18/ERIERL-48/OTP-14522: compiler: Fix live regs update on allocate in validator Take fail labels into account when determining liveness in block ops Conflicts: lib/compiler/src/beam_utils.erl
2017-08-16compiler: Fix live regs update on allocate in validatorLukas Larsson
The state without pruned registers was passed on to test_heap causing the validator to belive registers that aren't live actually are live.
2017-05-04Update copyright yearRaimo Niskanen
2017-04-22Make beam_validator track type formation for binary operationsMichal Muskala
Fixes https://bugs.erlang.org/browse/ERL-406 - a bug introduced in 0377592dc2238f561291be854d2ce859dd9a5fb1
2017-03-24compiler: Add is_tagged_tuple instructionBjörn-Egil Dahlberg
Rewrite the instruction stream on tagged tuple tests. Tagged tuples means a tuple of any arity with an atom as its first element. Typically records, ok-tuples and error-tuples. from: ... {test,is_tuple,Fail,[Src]}. {test,test_arity,Fail,[Src,Sz]}. ... {get_tuple_element,Src,0,Dst}. ... {test,is_eq_exact,Fail,[Dst,Atom]}. ... to: ... {test,is_tagged_tuple,Fail,[Src,Sz,Atom]}. ...
2017-01-12Add specs for the beam_*:module/2 functionsBjörn Gustavsson
2016-11-02Support math:fmod/2 BIF on compilerGuilherme Andrade
2016-09-21beam_validator: Correct reporting of y register numberBjörn Gustavsson
The error would be: {multiple_match_contexts,[{x,0},2]} instead of: {multiple_match_contexts,[{x,0},{y,2}]}
2016-09-14Merge branch 'maint'Björn Gustavsson
* maint: beam_validator: Handle unreachable instructions Turn off parallel make for start scripts Makefile
2016-09-13beam_validator: Handle unreachable instructionsBjörn Gustavsson
ab03678e introduced an optimization in the beam_z pass that could introduce unreachable code in BEAM files (a 'jump' instruction is removed after a 'raise' instruction, but the code following the target of the 'jump' is not removed). Since this situation happens very rarely, there is no point in adding another pass that can remove unreachable code after beam_z. Instead we will make sure that beam_validator can skip the unreachable code. Skipping unreachable code is already done in valfun_1/2 (for historical reasons), but we will also need to do it in val_dsetel/2.
2016-09-05Add math:floor/1 and math:ceil/1Björn Gustavsson
Add math:floor/1 and math:ceil/1 to avoid unnecessary conversions in floating point expressions. That is, instead of having to write float(floor(X)) as part of a floating point expressions, we can write simply math:floor(X).
2016-09-05Implement the new ceil/1 and floor/1 guard BIFsBjörn Gustavsson
Implement as ceil/1 and floor/1 as new guard BIFs (essentially part of Erlang language). They are guard BIFs because trunc/1 is a guard BIF. It would be strange to have trunc/1 as a part of the language, but not ceil/1 and floor/1.
2016-06-02Eliminate crash for map updates in guardsBjörn Gustavsson
beam_validator would complain that x(1) is uninitialized in a test_heap instruction when attempting to compile the following code with sys_core_fold turned off: foo(M) when not (M#{true := 0}); [M] -> ok. Simplified, the generated BEAM assembly code looked like this: test is_map BadMap x(0) put_map_exact Fail x(0) => x(1) ... jump BooleanStuff BadMap: move ok => x(1) jump Fail BooleanStuff: ... move Boolean => x(2) jump Build Fail: move false => x(2) Build: test_heap 2 3 %% x(0), x(1), x(2) must be live. ... That is, if put_map_exact failed, control would transfer to the label Fail without initializing x(1). Fix that by making sure that x(1) is initilized even if put_map_exact fails: test is_map BadMap x(0) put_map_exact BadLbl x(0) => x(1) ... jump OkLbl BadLbl: move ok => x(1) jump Fail OkLbl: jump BooleanStuff BadMap: move ok => x(1) jump Fail BooleanStuff: ... move Boolean => x(2) jump Build Fail: move false => x(2) Build: test_heap 2 3 %% x(0), x(1), x(2) must be live. ... Note that this situation is rare, and that other optimization passes (beam_dead and beam_jump in particular) will clean up this mess.
2016-05-31beam_validator: Strengthen validation of match statesBjörn Gustavsson
We want to find bugs in the compiler during compilation. Validation of match contexts was weak, which could allow serious bugs in the generated code to slip through.
2016-05-31beam_validator: Use a record representing the match contextBjörn Gustavsson
Using a record will make it much easier to add additional information.
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-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-04-13Merge branch 'henrik/update-copyrightyear'Henrik Nord
* henrik/update-copyrightyear: update copyright-year
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-15update copyright-yearHenrik Nord
2015-11-16beam_validator: Don't allow an 'undefined' entry label in a functionBjörn Gustavsson
Before 912fea0b beam_validator could validate disassembled files. That's probably why the entry label was allowed to be 'undefined'.
2015-11-16beam_validator: Remove obsolete DEBUG supportBjörn Gustavsson
No one has used the debug support in many years. Also, the debug support is not free. There are calls to lists:foreach/2 that will be executed even when debug support is turned off.
2015-09-07Merge branch 'maint'Björn-Egil Dahlberg
2015-09-04compiler: Add extra checks for get_map_elements in validatorBjörn-Egil Dahlberg
2015-08-21beam_validator: Don't allow x(1023) to be usedBjörn Gustavsson
In 45f469ca0890, the BEAM loader started to use x(1023) as scratch register for some instructions. Therefore we should not allow x(1023) to be used in code emitted by the compiler.
2015-06-18Change license text to APLv2Bruce Yinhe
2015-04-29beam_validator: Stop validating the 'aligned' flag for binariesBjörn Gustavsson
The run-time system stopped paying attention the 'aligned' flag in bit syntax construction and matching when bitstrings were introduced in language. The beam_asm compiler pass will crash if the 'aligned' flag is given in bit syntax instructions. beam_validator still validates the 'aligned' flag. Before 912fea0b712a (which removed the possibility to validate existing BEAM files), the 'aligned' flag could actually be encountered when validating a BEAM file. Since the validation of 'aligned' no longer serves any useful purpose, remove the validation code.
2015-04-29beam_validator: Clean up updating of types for y registerBjörn Gustavsson
set_type_y/3 is far too complicated. Note that we don't need to check the #st.numy field, because we will detect the error anyway because the information for the y register will be missing in the #st.y gb_tree. There is also a clause that would never match because of a spelling error (the first "n" was missing in "uninitialized"). That clause is not needed because the default clause will do fine. Furthermore, we can break out the special case for handling catch_end and similar instructions into a new function.
2015-04-23beam_validator: Remove support for removed BIF fault/1,2Björn Gustavsson
The fault/1,2 BIF was removed a long time ago.
2015-04-23beam_validator: Correct merging of statesBjörn Gustavsson
When merging two states, the following fields should be merged between the states: #st.x, #st.y, #st.numy, #st.ct. Everything else should be set to the default values in a new state.
2015-04-23beam_validator: Correct merging of y registersBjörn Gustavsson
When merging y registers, only the y registers that are found in both states should be retained.
2015-04-13beam_validator: No longer require strict literal term orderBjörn Gustavsson
The BEAM loader will now sort keys for maps during loading, so beam_validator should not require the keys to be ordered any order. However, we must still ensure that literals keys are unique (which was implicitly guaranteed by the strict ordering requirement).
2015-03-09beam_validator: Tighten tests of mapsBjörn Gustavsson
2015-03-09Introduce '%live' annotations with a complete register mapBjörn Gustavsson
As a preparation for fixing a bug, introduce a complete register map in the '%live' annotations.
2015-02-27beam_validator: Teach bif_type/3 and is_bif_safe/2 about is_map/1Björn Gustavsson
2015-02-20Merge branch 'bjorn/compiler/beam_validator'Björn Gustavsson
* bjorn/compiler/beam_validator: beam_validator: Exit immediately on crashes beam_validator: Remove the file/1 and files/1 functions beam_validator: Remove support for all other unsupported instructions beam_validator: Remove support for unsupported bit syntax instructions
2015-02-18beam_validator: Exit immediately on crashesBjörn Gustavsson
The beam_validator catches all exceptions and collect them. It makes more sense to don't catch 'error' and 'exit' exceptions, but to just print out the name of the current function and pass on the exception just as all other compilation passes do. Those kind of exceptions are the symptoms of the kind of severe but easily catched bugs that occur during development.
2015-02-18beam_validator: Remove the file/1 and files/1 functionsBjörn Gustavsson
Before the beam_validator was added as compiler pass, it was a standalone module that could analyse existing .beam files and .S files. Even though beam_validator has been part of the compiler for many releases, it still supports the analysis of .beam and .S files. To reduce the code bloat and to improve coverage of beam_validator, remove the file/1 and files/1 functions and all associated help functions. We'll need to update the test suite, since some of the checked in .S files have errors that beam_validator ignores, but that will not be accepted when running them throught the compiler using the 'from_asm' option. In particular, we will need to export all functions that should be validated (since the beam_clean pass will remove any function that is not possible to call).
2015-02-18beam_validator: Remove support for all other unsupported instructionsBjörn Gustavsson
2015-02-18beam_validator: Remove support for unsupported bit syntax instructionsBjörn Gustavsson
2015-02-18beam_validator: Tighten and simplify map validation codeBjörn Gustavsson
The assert_strict_literal_termorder/1 function is used to validate the get_map_elements and has_map_fields instructions. In neither case is it useful to allow an empty lists of fields, so we should no longer allow an empty list. The mmap/2 function is cute, but it is used in only one place, so it is much simpler to write a special-purpose function to extract the keys from the list of map pairs.
2015-01-14Add math:log2/1Olivier Girondel
2014-08-26compiler: Use variables in Map beam assmeblerBjörn-Egil Dahlberg
2014-02-23Deprecate pre-defined built-in typesHans Bolinder
The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(), set(), and tid() have been deprecated. They will be removed in OTP 18.0. Instead the types array:array(), dict:dict(), digraph:graph(), gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid() can be used. (Note: it has always been necessary to use ets:tid().) It is allowed in OTP 17.0 to locally re-define the types array(), dict(), and so on. New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2, queue:queue/1, and sets:set/1 have been added.