Bugzilla – Bug 319393
[PATCH] ParameterReference.Emit does not handle leave_copy
Last modified: 2007-09-15 21:24:23 UTC
---- Reported by peter@syncad.com 2005-10-25 11:11:07 MST ---- Please fill in this template when reporting a bug, unless you know what you are doing. Description of Problem: Mandrake linux versions (but happens with windows version too): mono-1.1.9.1-1mdk gmcs version 1.1.9.1 Unhandled InternalErrorException of the compiler when compiling the attached code. Steps to reproduce the problem: 1. save the source in the additional information to a.cs 2. run gmcs a.cs 3. Unhandled InternalErrorException of the compiler will happen. Actual Results: crash Expected Results: the compiled program How often does this happen? always Additional Information: Here is the source: using System; using System.Collections.Generic; class Test { static IEnumerable<int> FromTo(int from, int to) { while (from <= to) yield return from++; } static void Main() { IEnumerable<int> e = FromTo(1, 5); foreach (int x in e) { foreach (int y in e) { Console.Write("{0,3} ", x * y); } Console.WriteLine(); } } } ---- Additional Comments From bmaurer@users.sf.net 2005-11-07 21:37:37 MST ---- If you say ++from the code is also wrong, no assertion is thrown in the compiler, but a runtime exception occurs. ---- Additional Comments From bmaurer@users.sf.net 2005-11-07 21:57:35 MST ---- This is a simpler test case that only uses anon delegates, not iterators: using System; class Test { delegate void X (); static void Z (int i) { X x = delegate { int z = i ++; }; x (); } static void Main () { Z (1); } } ---- Additional Comments From bmaurer@users.sf.net 2005-11-08 17:01:03 MST ---- Created an attachment (id=168732) Patch ---- Additional Comments From bmaurer@users.sf.net 2005-11-08 17:01:31 MST ---- Created an attachment (id=168733) Test case ---- Additional Comments From miguel@ximian.com 2005-11-11 02:07:32 MST ---- Is there a reason to pass "ref LocalTemporary" around everywhere? It seems like it can be completely local to the routine that consumes it. What am I missing ---- Additional Comments From bmaurer@users.sf.net 2005-11-11 02:28:30 MST ---- Emit and EmitAssign must share a local variable: it is not enough to do clever manipulations with the stack using dup to pass the information between the two routines. In LocalVariableReference (which is very similar to this code), we have the LocalTemporary as an instance variable. However, that's not an option here, the closest we can get is passing it by ref. The other (probably cleaner) way to do it is to refactor this to look more like the local code. However, this may require more knowledge of the anonymous code than I have. One example where you need to use a local temporary in both methods is y++ where y is captured. The code path is: this.EmitAssign (ec, source, false, true) <load context> dup Binary.Emit () this.Emit (ec, true); ldfld y dup stloc temp end this.Emit (ec, true); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () stfld ldloc temp end this.EmitAssign (ec, source, false, true) Note how both Emit and EmitAssign need to use that temporary variable. ---- Additional Comments From miguel@ximian.com 2005-12-03 13:10:16 MST ---- Lets get this patch into SVN. Hari and Martin: can you provide feedback? ---- Additional Comments From bmaurer@users.sf.net 2005-12-03 22:27:46 MST ---- Fixed in svn. Imported an attachment (id=168732) Imported an attachment (id=168733) Unknown operating system unknown. Setting to default OS "Other".