Wrong pointer arithmetics in conjunction with constant folding
Very serious and important bug! Pointer arithmetics behaves wrong when doing several additions in a row, regardless of the base type. (Subtractions are mysteriously fine.) See this program: ```pascal {$mode objfpc} {$h+} {$typedaddress on} type pBaseType = ^BaseType; BaseType = uint32; // can be replaced with an arbitrary-sized array or record procedure Check(pstart, px: pBaseType; refIx: SizeInt; const desc: string); var ix: SizeInt; begin ix := px - pstart; writeln(desc, ' points at element #', ix); if ix = refIx then writeln('ok') else writeln('WRONG, must be #', refIx); writeln; end; var x: array[0 .. 19] of BaseType; p: pBaseType; begin p := pBaseType(x); Check(p, p + 2, 2, 'p + 2'); Check(p, p + 2 + 3, 5, 'p + 2 + 3'); Check(p, p + 2 + 3 + 5, 10, 'p + 2 + 3 + 5'); // These casts don't help. Check(p, pBaseType(pBaseType(p + 2) + 3) + 5, 10, 'pBaseType(pBaseType(p + 2) + 3) + 5'); // These work, but prevent constant folding. Check(p, pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5, 10, 'pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5'); Check(p, p + (2 + 3 + 5), 10, 'p + (2 + 3 + 5)'); Check(p, p + 2 + 3 + 5 + 7, 17, 'p + 2 + 3 + 5 + 7'); end. ``` and its output: ``` p + 2 points at element #2 ok p + 2 + 3 points at element #20 WRONG, must be #5 p + 2 + 3 + 5 points at element #100 WRONG, must be #10 pUint32(pUint32(p + 2) + 3) + 5 points at element #100 WRONG, must be #10 pUint32(pointer(pUint32(pointer(p + 2)) + 3)) + 5 points at element #10 ok p + (2 + 3 + 5) points at element #10 ok p + 2 + 3 + 5 + 7 points at element #428 WRONG, must be #17 ```
issue