Bug 319393 (MONO76550) - [PATCH] ParameterReference.Emit does not handle leave_copy
Summary: [PATCH] ParameterReference.Emit does not handle leave_copy
Status: RESOLVED FIXED
Alias: MONO76550
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Ben Maurer
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-25 18:11 UTC by Peter Hercek
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
Patch (4.87 KB, patch)
2005-11-09 00:01 UTC, Thomas Wiest
Details | Diff
Test case (501 bytes, text/plain)
2005-11-09 00:01 UTC, Thomas Wiest
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 19:36:14 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".