Age | Commit message (Collapse) | Author |
|
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)
|
|
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.
|
|
As a preparation for better optimizations in beam_type, a list
literal must be accepted as a 'cons'.
|
|
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.
|
|
* 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
|
|
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
|
|
It's time that we have a dedicated test suite for beam_bool.
|
|
Two test cases were not actually run. Even if their main purpose is to
ensure that the compiler doesn't crash, we always try to also run the
test case (when practial) to also ensure that the generated code is
correct.
|
|
Exported functions in this file should appear at the top of the file.
Also add missing spaces after commas.
|
|
I can't remember that clause ever trigger during development.
Remove it to eliminated an uncovered line.
|
|
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}.
|
|
|
|
All callers only calls code_at/2 for existing labels and they don't
handle the return value 'none'.
|
|
30cc5c902d moved try/3 instruction inside blocks, so the clause for
handling try/3 in live_opt/4 is never executed.
|
|
Two lines were never covered, because '[]' was used instead of 'nil'.
|
|
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}
|
|
Don't try to be nice. Since we now have good test suites for
Core Erlang, just let it crash.
|
|
|
|
We will get more information if we don't catch the exception.
|
|
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.
|
|
The inliner generates variable whose names are numeric. Run
the inliner to cover one more line in core_pp.
|
|
Several test cases in compile_SUITE (e.g. core/1) extracts the
abstract code from a BEAM file and runs the compiler on it.
It is only a waste of time to use the abstract code from
cloned versions of test case modules. That is, use record_SUITE,
but don't use record_no_opt_SUITE, record_post_opt_SUITE, or
record_inline_SUITE since they all contain essentially the same
abstract code.
|
|
Add is_cloned_mod(Mod) to determine whether Mod is the original
name for a module (e.g. record_SUITE) or a cloned module
(e.g. record_no_opt_SUITE).
|
|
Recent spring cleaning in the test suite left a line in sys_core_fold
dealing with an unnecessary catch uncovered.
|
|
Correct calculation of the number of parallel processes to use
when cover is used. It was supposed not to exceed 4 (according to
the comment), but it was calculated as the number of schedulers.
On my computer, having 8 schedulers, this change made the compiler
test suite with cover run almost twice as fast.
|
|
Rewrite code such as:
X = not_a_fun,
X()
to:
error({badfun,not_a_fun})
Also generate a warning.
|
|
|
|
'callback' and 'optional_callbacks' are no longer wild attributes.
|
|
* bjorn/compiler/core-erlang-fixes:
Slightly optimize core_pp
v3_core: Don't depend on sys_core_fold for cleaning up
|
|
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.
|
|
|
|
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.
|
|
With 'export_all' it is easy to add a new test case function
and forget to add its name to the list of test cases to run.
While we are it, remove unused functions and add the forgotten
test case on_load_inline/1.
|
|
It has not been used for ages.
|
|
|
|
|
|
|
|
long_string/1 was written to test that long string were handled
efficiently in beam_asm. Strings used to be stored in the string
table chunk, but are currently literals.
There does not seem that this test case is likely to find any bugs.
|
|
|
|
missing_testheap/1 is no longer relevant for the following reasons:
1) Because of the literal pool introduced in R12, no test_heap
instructions are needed in the guards.
2) beam_validator would abort the compilation if any needed test_heap
instructions were missing.
|
|
The integer_encoding/1 test is supposed to be run with a tighter
timetrap ensure that encoding of integer in BEAM files is efficient
enough.
|
|
beam_utils_SUITE didn't exist when the two test cases were written.
|
|
|
|
Obsoleted by guard_SUITE (especially literal_type_tests/1).
|
|
|
|
We used to put code that would crash the compiler into
compilation_SUITE_data. That way we would have a failing test case to
remind us to fix a bug.
Nowadays, we generally fix the bug and write the test case at the same
time. Therefore it makes more sense to put the test code directly into
a test suite.
Move out bin_syntax_1 through bin_syntax_5 test cases. Scrap
bin_syntax_6 because it does not longer seems to be relevant.
While we are it, rename the fun_shadow/1 test to size_shadow/1. Also
make sure that the code produces the correct result.
|
|
|
|
|
|
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.
|
|
* bjorn/compiler/remove-timestamps/OTP-13504:
Remove timestamps from BEAM files
|