trunk LLVM compiler generated wrong instructions for types with variant parts
Summary
LLVM compiler generates wrong getelementptr instructions when accessing record containing record with variant parts.
This simple rtl modification and test source was found after long analysis of the RTL heap errors using -gh option.
System Information
- **Operating system: Linux
- **Processor architecture: tested on aarch64 (but probably not cpu specific)
- **Compiler version: trunk
- Device:
Steps to reproduce
Apply the following simple patch to trunk:
muller@gcc103:~/pas/trunk/fpcsrc$ git diff rtl/unix/cthreads.pp
diff --git a/rtl/unix/cthreads.pp b/rtl/unix/cthreads.pp
index 11dd9a00c1..84fa562e26 100644
--- a/rtl/unix/cthreads.pp
+++ b/rtl/unix/cthreads.pp
@@ -680,12 +680,20 @@ function IntBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialStat
{$if defined(Linux) and not defined(Android)}
timespec: ttimespec;
{$ifend}
+{$ifdef DEBUG}
+ dist : ptrint;
+{$endif}
begin
new(plocaleventstate(result));
plocaleventstate(result)^.FManualReset:=AManualReset;
plocaleventstate(result)^.FWaiters:=0;
plocaleventstate(result)^.FDestroying:=False;
plocaleventstate(result)^.FIsSet:=InitialState;
+{$ifdef debug}
+ dist:=ptrint(@plocaleventstate(result)^.FDestroying)-ptrint(result);
+ if dist > sizeof(plocaleventstate(result)^) then
+ writeln(stderr,'problem within IntBasicEventCreate');
+{$endif}
{$if defined(Linux) and not defined(Android)}
res := pthread_condattr_init(@plocaleventstate(result)^.FAttr);
if (res <> 0) then
Example Project
Compile the following simple program
muller@gcc103:~/pas/check$ cat test-cthreads.pp
{$mode objfpc}
uses
cthreads,
classes;
var
i : longint;
threadvar
j : longint;
begin
i:=89;
j:=i;
writeln('j=',j);
end.
Using LLVM compiler (recompiled with -dDEBUG to exposed the rtl modification above), using:
ppca64 -gwl test-cthreads.pp
./test-cthread
What is the current bug behavior?
muller@gcc103:~/pas/check$ ./test-cthreads
problem within IntBasicEventCreate
j=89
An unhandled exception occurred at $0000000000431F64:
EAccessViolation: Access violation
$0000000000431F64
An unhandled exception occurred at $0000000000431F64:
EAccessViolation: Access violation
$0000000000431F64
$0000FFFEC4D07858
What is the expected (correct) behavior?
The output should only be:
j=89
and no error should happen.
Relevant logs and/or screenshots
Possible fixes
LLVM seems to have complicated strategies to cope with C-unions, and these probably need to be adapted correctly for Free Pascal.