[erlang-bugs] Core Erlang compilation problem
Bjorn Gustavsson
bgustavsson@REDACTED
Wed Jul 8 15:31:52 CEST 2009
On Fri, May 22, 2009 at 10:30 AM, Lars-Åke Fredlund<lfredlund@REDACTED> wrote:
> Lars-Åke Fredlund wrote:
>>
>> The attached Core Erlang module causes the compiler to crash:
>>
[...]
>>
>> but core_lint also complains:
>>
>> 2> compile:file("test.core",[return_errors, from_core, clint]).
>> {error,[{test,[{core_lint,{illegal_guard,{stop_mp,2}}}]}],
>> [{"no_file",[{none,sys_core_fold,result_ignored}]}]}
>>
>> Probably it is just a stupid oversight on my part, but I cannot see why
>> the code is not ok. Simply removing the second case clause, for instance,
>> causes the compilation to work?
It is far from obvious, but the problem is the following case statement
case <> of
<> when
call 'erlang':'is_record'(S,'t',14) ->
let <_cor6> = call 'erlang':'element'(7, S) in 'true'
end
which is illegal Core Erlang code, because there *must* always be a
clause that will be executed (a case statement in Core Erlang is not
allowed to fall through). The Core Erlang optimizer (sys_core_fold)
assumes that it is passed correct code, and it knows that if a case
only has one clause, it *must* match, and therefore the entire case
can be reduced to
let <_cor6> = call 'erlang':'element'(7, S) in 'true'
That is further optimized to
do call 'erlang':'element'(7, S)
'true'
This sequence is inside a guard, and currently the code generator
correctly does not handle a call to BIF when the return value is
ignored in a guard. It's low priority for me to fix that problem,
since it cannot happen (AFAIK) when compiling an Erlang module.
I suggest that you add a default clause to the end of the case to take
care of the case that S is not a record of the correct type.
/Bjorn
--
Björn Gustavsson, Erlang/OTP, Ericsson AB
More information about the erlang-bugs
mailing list