From 420826922145ae31605b0f9e0ab53bca41bc806c Mon Sep 17 00:00:00 2001
From: sergei <gorelkin@nanoreflex.ru>
Date: Sun, 11 Dec 2011 17:00:26 +0000
Subject: [PATCH] + Test case for bug #20827. The issue itself was fixed in
 r19668.

git-svn-id: trunk@19820 -
---
 .gitattributes          |   1 +
 tests/webtbs/tw20827.pp | 103 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)
 create mode 100644 tests/webtbs/tw20827.pp

diff --git a/.gitattributes b/.gitattributes
index ed2e6d5753..bc0417d17e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -11954,6 +11954,7 @@ tests/webtbs/tw20796a.pp svneol=native#text/pascal
 tests/webtbs/tw20796b.pp svneol=native#text/pascal
 tests/webtbs/tw20796c.pp svneol=native#text/pascal
 tests/webtbs/tw20821.pp svneol=native#text/pascal
+tests/webtbs/tw20827.pp svneol=native#text/plain
 tests/webtbs/tw20836.pp svneol=native#text/pascal
 tests/webtbs/tw20872a.pp svneol=native#text/pascal
 tests/webtbs/tw20872b.pp svneol=native#text/pascal
diff --git a/tests/webtbs/tw20827.pp b/tests/webtbs/tw20827.pp
new file mode 100644
index 0000000000..1c4786e67c
--- /dev/null
+++ b/tests/webtbs/tw20827.pp
@@ -0,0 +1,103 @@
+
+// TObject-descended enumerators together with Level 2 optimization
+// were generating invalid code on targets with non-fixed stack (i386-win32, i386-linux).
+
+{$MODE OBJFPC}
+{$INTERFACES CORBA}
+{$COPERATORS ON}
+{$INLINE ON}
+{$OPTIMIZATION ON}
+
+
+type TNode = class
+  ID : byte;
+  MyType : byte;
+  Amount : word;
+  constructor Create();
+  function IsOK : boolean;
+end;
+
+type TContainer = class;
+
+type TContainerEnumerator = class
+  Contents : TNode;
+  IsDone : boolean;
+  constructor Create(Parent : TContainer);
+  function MoveNext : Boolean;
+  function GetCurrent : TNode;
+  property Current : TNode read GetCurrent;
+end;
+
+type TContainer = class
+  Contents : TNode;
+  constructor Create(node : TNode);
+  function Seek(SeekID : byte) : TNode;
+  function GetEnumerator : TContainerEnumerator;
+end;
+
+constructor TNode.Create();
+begin
+  ID := 20;
+  MyType := 5;
+  Amount := 24;
+end;
+
+function TNode.IsOK : boolean;
+begin
+  Exit(MyType = 5);
+end;
+
+
+constructor TContainerEnumerator.Create(Parent : TContainer);
+begin
+  Contents := Parent.Contents;
+  IsDone := false;
+end;
+
+function TContainerEnumerator.MoveNext : Boolean;
+begin
+  if IsDone then Exit(false);
+  IsDone := true;
+  Exit(true);
+end;
+
+function TContainerEnumerator.GetCurrent : TNode;
+begin
+  Exit(Contents);
+end;
+
+constructor TContainer.Create(node : TNode);
+begin
+  Contents := node;
+end;
+
+function TContainer.Seek(SeekID : byte) : TNode;
+var node : TNode;
+    amount : word;
+begin
+  Seek := nil;
+  amount := 255;
+
+  for node in Self do
+    if node.IsOK then
+      if node.ID = SeekID then
+        if node.Amount < amount then
+        begin
+          Seek := node;
+          amount := node.Amount;
+        end;
+end;
+
+function TContainer.GetEnumerator : TContainerEnumerator;
+begin
+  Exit(TContainerEnumerator.Create(Self))
+end;
+
+var node : TNode;
+    container : TContainer;
+begin
+  node := TNode.Create();
+  container := TContainer.Create(node);
+  if container.Seek(20) = nil then Halt(1)
+  else writeln('success');
+end.