Re: [ooc-compiler] Compiler error
Brought to you by:
mva
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 01:27:36
|
Hi Frank,
I checked this out and it seems to be a bug in gcc's optimizer.
The Oberon-2 source code is this:
PROCEDURE IsEmpty* (list:Header): BOOLEAN;
BEGIN RETURN list.first=NIL
END IsEmpty;
OOC generates this object code:
OOC_CHAR8 L__IsEmpty(const struct L__Header *list__ref) {
register OOC_INT32 i0;
OOC_ALLOCATE_VPAR(list,L__Header ,1)
OOC_INITIALIZE_VPAR(list__ref,list,L__Header ,8)
i0 = (OOC_INT32)*(OOC_INT32*)(OOC_INT32)list;
return (i0==0);
;
}
It allocates a local copy of the Header record (OOC_ALLOCATE_VPAR).
It copies "list" since the record is passed by value
(OOC_INITIALIZE_VPAR just calls memcpy).
It then tests the "first" field, which just happens to be the first
element in the structure.
With the normal optimization level (-O2), gcc generates this:
.globl L__IsEmpty
.type L__IsEmpty, @function
L__IsEmpty:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl -8(%ebp), %eax
leave
testl %eax, %eax
sete %al
ret
This is just plain wrong. for some reason it has eliminated the call to
memcpy, so its testing the value of an uninitialised local record.
Compiling the same C code without optimisation gives this:
globl L__IsEmpty
.type L__IsEmpty, @function
L__IsEmpty:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $36, %esp
movl $8, 8(%esp)
movl 8(%ebp), %eax
movl %eax, 4(%esp)
leal -16(%ebp), %eax
movl %eax, (%esp)
call memcpy
leal -16(%ebp), %eax
movl (%eax), %ebx
testl %ebx, %ebx
sete %al
addl $36, %esp
popl %ebx
popl %ebp
ret
.size L__IsEmpty, .-L__IsEmpty
This code actually works fine and gives the right output.
I'm not sure what to recommend here. Obviously care should be taken with
this version of GCC. The fact that OOC builds itself fine indicates that
the problem is probably fairly rare. For efficiency, you would normally
pass records by reference anyway. I think gcc has decided to eliminate
the call to memcpy because it thinks the result is unused. When I added
a printf statement (list[0].first) after the OOC_INITIALIZE_VPAR the
problem went away. I expect that for non-trivial code its much less
likely to occur. If you want to be perfectly safe you could run oo2c
without optimization, or see if the problem is resolved in later
versions of gcc.
Cheers,
Stewart
Frank Hrebabetzky wrote:
> On 07/30/2010 01:30 AM, Stewart Greenhill wrote:
>
>>> oo2c --version
>>> oo2c/gcc 2.1.11
>>> gcc --version
>>> gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
>
> This remembers me that the MinGW folks recently had considerable
> difficulties with the update to a newer gcc version. I followed the
> discussion without understanding anything. Don't know whether this is
> relevant here.
|