inlined function does not produce same result as normal function
## Summary Normal function produces expected result, same function but inlined returns different and wrong result. ## System Information - **Operating system:** Linux_DEBIAN_bookworm(12) - **Processor architecture:** x86-64 - **Compiler version:** Free Pascal Compiler version 3.2.2+dfsg-20 [2023/03/30] for x86_64 - **Device:** Computer - **Compiler Optimization Level:** None (0) ## Steps to reproduce The example provided is full pascal program. Just compile and run. The inline test will fail with assertion error. ## Example Project (64-bit only) ``` program inline_problem; {$mode DELPHI} {$DEFINE DEBUG} {$ASSERTIONS ON} type TTest = class sealed strict private type TFoobar = packed record A: uint16; B: uint16; C: uint16; end; TA = packed record Foobar: TFoobar; R: uint16; procedure Print; end; TB = packed record R: uint16; Foobar: TFoobar; procedure Print; end; strict private class function Convert_A_into_B(const A: Pointer): Pointer; static; class function Convert_A_into_B_INLINED(const A: Pointer): Pointer; inline; static; public class procedure PerformNormalTest; static; class procedure PerformInlinedTest; static; end; class function TTest.Convert_A_into_B(const A: Pointer): Pointer; var LA: TA absolute A; LB: TB absolute Result; begin LB.R := LA.R; LB.Foobar.A := LA.Foobar.A; LB.Foobar.B := LA.Foobar.B; LB.Foobar.C := LA.Foobar.C; end; class function TTest.Convert_A_into_B_INLINED(const A: Pointer): Pointer; var LA: TA absolute A; LB: TB absolute Result; begin LB.R := LA.R; LB.Foobar.A := LA.Foobar.A; LB.Foobar.B := LA.Foobar.B; LB.Foobar.C := LA.Foobar.C; end; class procedure TTest.PerformNormalTest; var A: TObject; B: Pointer; begin A := TObject.Create; B := nil; try Writeln; Writeln('Normal Test'); Writeln('-----------'); TA(A).Print; Writeln; B := Convert_A_into_B(A); TB(B).Print; Writeln('-----------'); Assert(TA(A).Foobar.A = TB(B).Foobar.A, 'A values do not match'); Assert(TA(A).Foobar.B = TB(B).Foobar.B, 'B values do not match'); Assert(TA(A).Foobar.C = TB(B).Foobar.C, 'C values do not match'); Writeln('Everything ok'); finally A.Free; end; end; class procedure TTest.PerformInlinedTest; var A: TObject; B: Pointer; begin A := TObject.Create; B := nil; try Writeln; Writeln('INLINE Test'); Writeln('-----------'); TA(A).Print; Writeln; B := Convert_A_into_B_INLINED(A); TB(B).Print; Writeln('-----------'); Assert(TA(A).Foobar.A = TB(B).Foobar.A, 'A values do not match'); Assert(TA(A).Foobar.B = TB(B).Foobar.B, 'B values do not match'); Assert(TA(A).Foobar.C = TB(B).Foobar.C, 'C values do not match'); Writeln('Everything ok'); finally A.Free; end; end; procedure TTest.TA.Print; begin Writeln('A = ', Foobar.A); Writeln('B = ', Foobar.B); Writeln('C = ', Foobar.C); Writeln('R = ', R); end; procedure TTest.TB.Print; begin Writeln('A = ', Foobar.A); Writeln('B = ', Foobar.B); Writeln('C = ', Foobar.C); Writeln('R = ', R); end; begin TTest.PerformNormalTest; TTest.PerformInlinedTest; end. ``` ## What is the expected (correct) behavior? The result of inlined function should be the same as that of normal function. ## Relevant logs and/or screenshots ``` ./inline_problem Normal Test ----------- A = 28736 B = 35360 C = 32527 R = 0 A = 28736 B = 35360 C = 32527 R = 0 ----------- Everything ok INLINE Test ----------- A = 28736 B = 35360 C = 32527 R = 0 A = 0 B = 0 C = 0 R = 0 ----------- A values do not match (inline_problem.lpr, line 103). ```
issue