|
@@ -0,0 +1,41 @@
|
|
|
+{ %OPT=-O3 }
|
|
|
+{$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
|
|
|
+ begin
|
|
|
+ writeln('WRONG, must be #', refIx);
|
|
|
+ halt(1);
|
|
|
+ end;
|
|
|
+ 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.
|