tcse2.pp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. { %OPT=-OG2}
  2. {$r+}
  3. type
  4. tsubr = 1..100000;
  5. tarr = array[1..100000] of longint;
  6. function test(b: tsubr): longint;
  7. begin
  8. test := b;
  9. end;
  10. var
  11. p: ^longint;
  12. l: longint;
  13. a, a2: tarr;
  14. begin
  15. getmem(p,4);
  16. p^ := 100000;
  17. l := 5;
  18. { clear the optimizer state }
  19. asm
  20. end;
  21. {$r-}
  22. { get p^ in eax, the following statement generates the code }
  23. { movl A,%eax }
  24. { movl (%eax),%eax }
  25. a[p^] := l;
  26. {$r+}
  27. { now, p^ gets rangechecked, this generates the code }
  28. { movl A,%eax (1) }
  29. { movl (%eax),%ecx (1) }
  30. { ... }
  31. { call rangecheck_procedure }
  32. { pushl (%eax) }
  33. { }
  34. { With the bug in the optimizer, the instructions marked with (1) are }
  35. { replaced by }
  36. { movl %eax,%ecx }
  37. { }
  38. { and as such the "pushl (%eax)" pushes a wrong value afterwards }
  39. l := test(p^);
  40. if l <> 100000 then
  41. begin
  42. writeln('Problem 1!');
  43. halt(1);
  44. end;
  45. p^ := 5;
  46. l := 5;
  47. { clear the optimizer state }
  48. asm
  49. end;
  50. {$r-}
  51. { the following moves p^ in %edx }
  52. a2[l] := a[p^];
  53. {$r+}
  54. { same test as before, but now the original value comes from edx }
  55. { instead of that it is already in eax (so check that it doesn't }
  56. { replace the }
  57. { movl P,%eax }
  58. { movl (%eax),%ecx }
  59. { with }
  60. { movl %edx,%ecx }
  61. l := test(p^);
  62. if l <> 5 then
  63. begin
  64. writeln('Problem 2!');
  65. halt(1);
  66. end;
  67. freemem(p,4);
  68. end.