C-style in-place assignments sometimes compute LHS twice
Original Reporter info from Mantis: runewalsh
-
Reporter name:
Original Reporter info from Mantis: runewalsh
- Reporter name:
Description:
First half of the example gives not the result I expect. Namely, it behaves as if expression
a[F()] += 1
has been rewritten to
a[F()] := a[F()] + 1
instead of
temp_ptr := @a[F()];
temp_ptr^ += 1
Meanwhile, the second half that uses
F()^ += 1
works right the way I expect from in-place modification operators.
Steps to reproduce:
{$mode objfpc} {$h+} {$coperators on}
var
a: array[0 .. 3] of uint32;
whatToIncrementNext: SizeUint;
procedure Reset;
begin
whatToIncrementNext := 0;
FillChar(pUint32(a)^, length(a) * sizeof(a[0]), 0);
writeln('Before: ', a[0], ' ', a[1], ' ', a[2], ' ', a[3], LineEnding);
end;
function NextIndex: SizeUint;
begin
result := whatToIncrementNext;
writeln('Incrementing ', whatToIncrementNext, 'th element');
whatToIncrementNext := (whatToIncrementNext + 1) mod length(a);
end;
function NextPtr: pUint32;
begin
result := @a[whatToIncrementNext];
writeln('Incrementing ', whatToIncrementNext, 'th element');
whatToIncrementNext := (whatToIncrementNext + 1) mod length(a);
end;
var
incr: uint32;
begin
Reset;
for incr in specialize TArray<uint32>.Create(1, 2, 4, 8) do
begin
writeln('a[NextIndex()] += ', incr, '...');
a[NextIndex] += incr;
writeln(a[0], ' ', a[1], ' ', a[2], ' ', a[3], LineEnding);
end;
Reset;
for incr in specialize TArray<uint32>.Create(1, 2, 4, 8) do
begin
writeln('NextPtr()^ += ', incr, '...');
NextPtr^ += incr;
writeln(a[0], ' ', a[1], ' ', a[2], ' ', a[3], LineEnding);
end;
end.
Additional information:
My output is:
Before: 0 0 0 0
a[NextIndex()] += 1...
Incrementing 0th element
Incrementing 1th element
1 0 0 0
a[NextIndex()] += 2...
Incrementing 2th element
Incrementing 3th element
1 0 2 0
a[NextIndex()] += 4...
Incrementing 0th element
Incrementing 1th element
4 0 2 0
a[NextIndex()] += 8...
Incrementing 2th element
Incrementing 3th element
4 0 8 0
Before: 0 0 0 0
NextPtr()^ += 1...
Incrementing 0th element
1 0 0 0
NextPtr()^ += 2...
Incrementing 1th element
1 2 0 0
NextPtr()^ += 4...
Incrementing 2th element
1 2 4 0
NextPtr()^ += 8...
Incrementing 3th element
1 2 4 8
Mantis conversion info:
- Mantis ID: 39206
- Build: r49583 [2021/07/08]
- Version: 3.3.1
- Fixed in version: 3.3.1
- Fixed in revision: 49608 (#0d6a1d24)