[Mono-bugs] [Bug 492329] New: gmcs generated invalid IL code for storing a new object in a generic out/ref parameters (regression from 2.2).

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Mon Apr 6 01:57:49 EDT 2009


http://bugzilla.novell.com/show_bug.cgi?id=492329


           Summary: gmcs generated invalid IL code for storing a new
                    object in a generic out/ref parameters (regression
                    from 2.2).
    Classification: Mono
           Product: Mono: Compilers
           Version: 2.4.x
          Platform: x86
        OS/Version: Ubuntu
            Status: NEW
          Severity: Major
          Priority: P5 - None
         Component: C#
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: sgroot at tkl.iis.u-tokyo.ac.jp
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---


Created an attachment (id=284172)
 --> (http://bugzilla.novell.com/attachment.cgi?id=284172)
Compilable sample demonstrating the problem.

User-Agent:       Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729;
Media Center PC 6.0)

If a function has a out or ref parameter of a generic type, and the function
directly assigned the result of an instantiation of that type to the parameter,
the gmcs compiler generates invalid IL code. The compiler does not push the
address of the argument onto the stack. This problem did not occur with Mono
2.2; it is new in the 2.4 compiler.

The following simple code demonstrates this problem (it uses an out param, but
the same thing happens with a ref param):

class Bug<T> where T : new()
{
  public void CreateObject(out T param)
  {
    param = new T();
  }
}

When attempting to execute that code, the following exception is thrown:
System.InvalidProgramException: Invalid IL code in BugTest.Bug`1:CreateObject
(T&): IL_0026: stobj     0x1b000001

This is the IL listing generated by the 2.4 compiler:
method public hidebysig instance void CreateObject([out] !T& param) cil
managed
{
    .maxstack 3
    .locals init (
        [0] !T local)
    L_0000: ldloca.s local
    L_0002: initobj !T
    L_0008: ldloc.0 
    L_0009: box !T
    L_000e: brfalse L_0021
    L_0013: ldloca.s local
    L_0015: initobj !T
    L_001b: ldloc.0 
    L_001c: br L_0026
    L_0021: call !!0 [mscorlib]System.Activator::CreateInstance<!T>()
    L_0026: stobj !T
    L_002b: ret 
}

If you trace the stack contents in this function, you can see that the address
of param is never pushed onto the stack, so the stack holds only one item (the
new object) when L_0026 is reached, while is should hold two (the address and
the new object) for stobj.

The IL generated by the 2.2 compiler looks identical except the first
instruction is ldarg.1, so the problem does not occur there.

The problem only occurs when assigning directly to the out/ref param. When
using the following simple work-around, the problem does not occur:
T local = new T();
param = local;

Reproducible: Always

Steps to Reproduce:
1. Compile the attached bug.cs file using the mono 2.4 compiler (just "gmcs
bug.cs" will do).
2. Run the program using mono.
3. Observe the exception.
Actual Results:  
The C# compiler generated invalid IL code, causing an InvalidProgramException
during JIT compilation.

Expected Results:  
I expected the Mono 2.4 C# compiler to generate the correct IL code, identical
to the correct code generated by the Mono 2.2 C# compiler.

-- 
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list