Please do not reply to this email- if you want to comment on the bug, go to the URL shown below and enter your comments there.
Changed by [EMAIL PROTECTED] http://bugzilla.ximian.com/show_bug.cgi?id=75670 --- shadow/75670 2005-07-30 13:42:57.000000000 -0400 +++ shadow/75670.tmp.25031 2005-07-30 13:42:57.000000000 -0400 @@ -0,0 +1,227 @@ +Bug#: 75670 +Product: Mono: Compilers +Version: 1.1 +OS: +OS Details: GNU/Linux +Status: NEW +Resolution: +Severity: +Priority: Wishlist +Component: C# +AssignedTo: [EMAIL PROTECTED] +ReportedBy: [EMAIL PROTECTED] +QAContact: [EMAIL PROTECTED] +TargetMilestone: --- +URL: +Cc: +Summary: Yield Destroys Reference Values in Current Stack Frame + +Description of Problem: + +Building straight from SVN on 7/30, yielding a value in an iterator, at +least in some cases, appears to set variables in the current stack frame to +null after the yield. That's the symptom, at least, if not the problem. +Here's code to repro. This compiles and works as expected in csc 2.0 beta 2. + +==== Begin Code ==== + +// Yield file members of the current directory first. +foreach (string child in Directory.GetFiles(Path.Path)) +{ + Console.WriteLine("Match file: " + ((child == null) ? "null" : child)); + yield return new XrcFSPath(child); +} + +// Delve into directories to find grandchildren, etc. +foreach (string child in Directory.GetDirectories(Path.Path)) +{ + Console.WriteLine("Match directory: " + ((child == null) ? "null" : child)); + XrcFSPath dirPath = new XrcFSPath(child); + // Yield the child itself. + yield return dirPath; + + // BUG NOTE: Expect dirPath to not be null here, but "DirPath is null" + // gets printed. + Console.WriteLine("DirPath is " + ((dirPath == null) ? "null" : +dirPath.Path)); + // Yield all grandchildren, etc., through this child. + XrcFSPathDescendantIterator childItor = new +XrcFSPathDescendantIterator(dirPath); + foreach (IXrcDataElement elem in childItor) + yield return elem; +} + +==== End Code ==== + +Weirder: After "yield return dirPath", 'child' also seems to be set to +null: if I try to construct a new XrcFSPath w/ 'child' to work around the +bug, I get an ArgumentNullException b/c 'child' has become null after the +"yield return dirPath". + + + +Actual Results: + +Here's output of a small sample (source included below). You have to run +the code in a directory that contains at least one subdirectory to see the +problem. + +==== Program Output Begin ==== +Match file: ./Xircle.Core.dll +./Xircle.Core.dll +Match file: ./Xircle.FS.dll +./Xircle.FS.dll +Match directory: ./testdir +./testdir +DirPath is null + +Unhandled Exception: System.ArgumentNullException: Argument cannot be null. +Parameter name: path +in <0x00040> TestCode.XrcFSPathIterator:.ctor (TestCode.XrcFSPath path) +in <0x0000d> TestCode.XrcFSPathDescendantIterator:.ctor (TestCode.XrcFSPath +path) +in <0x0025c> +TestCode.XrcFSPathDescendantIterator+<GetEnumerator>__0:MoveNext () +in <0x0014b> TestCode.Program:Main (System.String[] args) +==== Program Output End ==== + + +Expected Results: + +Here's what the output should look like, assuming one file in testdir named +testfile. + +==== Program Output Begin ==== +Match file: ./Xircle.Core.dll +./Xircle.Core.dll +Match file: ./Xircle.FS.dll +./Xircle.FS.dll +Match directory: ./testdir +./testdir +DirPath is ./testdir +Match file: ./testdir/testfile +./testdir/testfile +==== Program Output End ==== + + +How often does this happen? + +Repeatable. + + +Additional Information: + +Here's a sample program that illustrates the problem. + + +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace TestCode +{ + public class Program + { + static void Main(String[] args) + { + XrcFSPath rootPath = new XrcFSPath("."); + XrcFSPathDescendantIterator itor = new +XrcFSPathDescendantIterator(rootPath); + foreach(IXrcDataElement elem in itor) + { + Console.WriteLine(((XrcFSPath) elem).Path); + } + } + } + + public class XrcFSPathDescendantIterator : XrcFSPathIterator + { + public XrcFSPathDescendantIterator(XrcFSPath path) + : base(path) + { } + + public override IEnumerator<IXrcDataElement> GetEnumerator() + { + // NOTE: This is a very straightforward and naive implementation. + // It is recursive and creates a bunch of iterator objects. A + // non-recursive solution should probably be coded up when there + // is time. + + // Yield file members of the current directory first. + foreach (string child in Directory.GetFiles(Path.Path)) + { +Console.WriteLine("Match file: " + ((child == null) ? "null" : child)); + yield return new XrcFSPath(child); + } + + // Delve into directories to find grandchildren, etc. + foreach (string child in Directory.GetDirectories(Path.Path)) + { +Console.WriteLine("Match directory: " + ((child == null) ? "null" : child)); + XrcFSPath dirPath = new XrcFSPath(child); + // Yield the child itself. + yield return dirPath; + +Console.WriteLine("DirPath is " + ((dirPath == null) ? "null" : dirPath.Path)); + // Yield all grandchildren, etc., through this child. + XrcFSPathDescendantIterator childItor = + new XrcFSPathDescendantIterator(dirPath); + foreach (IXrcDataElement elem in childItor) + yield return elem; + } + } + } + + public class XrcFSPath : IXrcDataElement + { + private string m_path; + + public XrcFSPath(string path) + { + if (path == null) + throw new ArgumentNullException("path"); + + m_path = path; + } + + public string Path + { + get { return m_path; } + } + } + + public abstract class XrcFSPathIterator : IXrcDataIterator + { + private XrcFSPath m_path; + + public XrcFSPathIterator(XrcFSPath path) + { + if (path == null) + throw new ArgumentNullException("path"); + + m_path = path; + } + + public XrcFSPath Path + { + get { return m_path; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((XrcFSPathIterator) this).GetEnumerator(); + } + + public abstract IEnumerator<IXrcDataElement> GetEnumerator(); + } + + public interface IXrcDataElement + { + // Elided... + } + + public interface IXrcDataIterator : IEnumerable<IXrcDataElement> + { + } +} _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
