123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- { %OPT=-OG2}
- {$r+}
- type
- tsubr = 1..100000;
- tarr = array[1..100000] of longint;
- function test(b: tsubr): longint;
- begin
- test := b;
- end;
- var
- p: ^longint;
- l: longint;
- a, a2: tarr;
- begin
- getmem(p,4);
- p^ := 100000;
- l := 5;
- { clear the optimizer state }
- asm
- end;
- {$r-}
- { get p^ in eax, the following statement generates the code }
- { movl A,%eax }
- { movl (%eax),%eax }
- a[p^] := l;
- {$r+}
- { now, p^ gets rangechecked, this generates the code }
- { movl A,%eax (1) }
- { movl (%eax),%ecx (1) }
- { ... }
- { call rangecheck_procedure }
- { pushl (%eax) }
- { }
- { With the bug in the optimizer, the instructions marked with (1) are }
- { replaced by }
- { movl %eax,%ecx }
- { }
- { and as such the "pushl (%eax)" pushes a wrong value afterwards }
- l := test(p^);
- if l <> 100000 then
- begin
- writeln('Problem 1!');
- halt(1);
- end;
- p^ := 5;
- l := 5;
- { clear the optimizer state }
- asm
- end;
- {$r-}
- { the following moves p^ in %edx }
- a2[l] := a[p^];
- {$r+}
- { same test as before, but now the original value comes from edx }
- { instead of that it is already in eax (so check that it doesn't }
- { replace the }
- { movl P,%eax }
- { movl (%eax),%ecx }
- { with }
- { movl %edx,%ecx }
- l := test(p^);
- if l <> 5 then
- begin
- writeln('Problem 2!');
- halt(1);
- end;
- freemem(p,4);
- end.
|