[Mono-bugs] [Bug 60316][Maj] New - MCS 0.96 fails to emit a foreach on a struct collection property

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Wed, 16 Jun 2004 19:49:06 -0400 (EDT)


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 dge@softec.st.

http://bugzilla.ximian.com/show_bug.cgi?id=60316

--- shadow/60316	2004-06-16 19:49:06.000000000 -0400
+++ shadow/60316.tmp.25909	2004-06-16 19:49:06.000000000 -0400
@@ -0,0 +1,113 @@
+Bug#: 60316
+Product: Mono: Compilers
+Version: unspecified
+OS: 
+OS Details: Linux Mandrake 10.0 Official
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Major
+Component: C#
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: dge@softec.st               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: MCS 0.96 fails to emit a foreach on a struct collection property 
+
+MCS 0.96 fails to emit a foreach statement. It fails when the collection is
+a struct return by value from a property. Same code are correctly compiled
+by CSC. Note that the sample provided here has no sense, but of course, I
+have stumbled on this in a real and useful situation.
+
+Minimal code sample:
+
+using System;
+using System.Collections;
+
+class MainClass {
+	// A Collection (using struct)
+	public struct ACollection : IEnumerable	{
+		private int mSize;
+
+		public ACollection(int i) { mSize = i; }
+		public IEnumerator GetEnumerator() {
+			return (IEnumerator) new ACollectionEnumerator(mSize); 
+		}
+	}
+	public class ACollectionEnumerator : IEnumerator {
+		private int mSize;
+		private int mVal;
+		
+		public ACollectionEnumerator(int i)	{ mSize = i; }
+		
+		public void First()	{ mVal = 1;	}
+		public bool MoveNext() { 
+			mVal++;
+			return ( mVal < mSize );
+		}
+		public void Reset()	{ mVal = 0;	}
+		
+		public object Current {
+			get {
+				if( mVal != 0 )
+					return mVal;
+				throw new System.InvalidOperationException();
+			}
+		}	
+	}
+	
+	// An embedding class
+	public class AEmbeddingClass {
+		private ACollection mColl;
+		
+		public AEmbeddingClass(int size) {
+			mColl = new ACollection(size);
+		}
+		public ACollection ACollProps {
+			get	{
+				return mColl;
+			}
+		}
+	}
+
+	// Main
+	public static void Main(string[] args)	{
+		AEmbeddingClass s = new AEmbeddingClass(5);
+		
+		// Foreach that mcs fails to emit
+		foreach(int i in s.ACollProps) {
+			Console.WriteLine("{0}",i);
+		}
+	}
+}
+
+Actual Results:
+Exception caught by the compiler while compiling:
+   Block that caused the problem begin at:
+/home/denisg/MonoDevelopProjects/Hello/ForEach/Main.cs: (49)
+                     Block being compiled: [Internal: (1),Internal: (1)]
+System.Exception: Expr Mono.CSharp.PropertyExpr of type
+MainClass+ACollection does not implement IMemoryLocation
+	in Foreach.EmitCollectionForeach (Mono.CSharp.EmitContext)
+	in Foreach.DoEmit (Mono.CSharp.EmitContext)
+	in Statement.Emit (Mono.CSharp.EmitContext)
+	in Block.DoEmit (Mono.CSharp.EmitContext)
+	in Block.Emit (Mono.CSharp.EmitContext)
+	in Block.DoEmit (Mono.CSharp.EmitContext)
+	in Block.Emit (Mono.CSharp.EmitContext)
+	in EmitContext.EmitTopBlock (Mono.CSharp.Block,
+Mono.CSharp.InternalParameters, Mono.CSharp.Location)
+
+Expected Results:
+Compilation succeeded
+
+How often does this happen? 
+Always
+
+Additional Information:
+Replacing the struct ACollection by a class and everything works perfectly.
+Alternatively, storing a copy of the property in a temporary variable of
+main and use it in the foreach also solve the problem.
+This is not a regression, already present in version 0.29 and probably before.