[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