Browse Source

+ to000000.pp

Jonas Maebe 27 years ago
parent
commit
ccd97bbec9
2 changed files with 55 additions and 0 deletions
  1. 2 0
      tests/README
  2. 53 0
      tests/to000000.pp

+ 2 - 0
tests/README

@@ -28,3 +28,5 @@ ts010015.pp       tests typed files.
 ts10100.pp        tests for delphi object model
 -
 ts101xx.pp
+
+to000000          shows when uncertain optimizations can cause wrong code

+ 53 - 0
tests/to000000.pp

@@ -0,0 +1,53 @@
+Program UnsureOptsFail;
+{This program shows how unsure optimizations can cause wrong code if you
+ program Silly Things (TM)
+
+ The principle is always the same:
+
+ you have a normal variable (local or global) and a pointer to it in one way
+ or another (be it a normal pointer or a var parameter).
+
+ a) you first cause the value from the memeory location to be loaded in a
+    register (e.g. by using the normal variable as an array index)
+ b) next you assign a new value to the memory location (e.g. through the
+    pointer)
+ c) finally, you compare the two values
+
+ Of course you can also use the pointer as an array index and assign a new
+ value to the normal variuable, that doesn't change anything).
+
+ The problem is that the value of the first load is still in a register, so
+ it isn't loaded from memory again, so you compare the old value with the
+ new one.
+
+ Note: this code doesn4t function correctly only when compiled with uncertain
+ optimizations on. All other forms of optimization are completely safe.
+ }
+
+var l: longint;
+    p: ^longint;
+    a: Array[1..10] of byte;
+
+Procedure ChangeIt(var t: longint);
+{The same principle as in the main program, only here we have a var parameter
+ instead of a "normal" pointer. If l is passed to this procedure, it doesn't
+ function right.}
+Begin
+  t := 1;
+  If t = l Then   {t gets loaded in a register (eax)}
+    Begin
+      l := 2;
+      If t <> l then
+        Writeln('She can''t take any more or she''ll blow, captain!');
+    End;
+End;
+
+begin
+  p := @l;     {p points to l}
+  l := 1;
+  a[p^] := 2;  {load p^ in a register (eax in this case)}
+  l := 2;      {change the value of l}
+  If p^ <> l
+    Then Writeln('Houston, we have a problem!');
+  ChangeIt(l);
+End.