See the question and my original answer on StackOverflow

I don't think it's a bug; it looks more like "COM voodoo" as you say. Under the hood, the C# compiler emits something that is in fact correct, like this:

private static void Foo(IFoo o)
{
    ...
    Guid g = Guid.NewGuid();
    Guid <>r__ComRefCallLocal0 = g;
    Bar(o, ref <>r__ComRefCallLocal0);
    ...
}

C# is in fact full of tricks. If you add a method to IFoo, like this for example,

[ComImport, Guid("cb4ac859-0589-483e-934d-b27845d5fe74")]
interface IFoo
{
    void Test([Optional] ref object test);
}

you, again, will be able to declare this in C# 4:

static void Foo(IFoo o)
{
    Guid g = Guid.NewGuid();
    o.Test(g);
}

Of course, all this only works because CSC.EXE has an intimate knowledge of the ComImport attribute. These new magic Interop tricks were added to C# 4.0 to be able to easily interop with existing COM interfaces. Well, for Microsoft Office interfaces and methods mostly, and especially the armies of dreadful 'ref missing' parameters :-)

I don't think this is fully specified anywhere. This is all what the C# 4 specification has to say:

17.5 Attributes for Interoperation Note: This section is applicable only to the Microsoft .NET implementation of C#. 17.5.1 Interoperation with COM and Win32 components The .NET run-time provides a large number of attributes that enable C# programs to interoperate with components written using COM and Win32 DLLs. For example, the DllImport attribute can be used on a static extern method to indicate that the implementation of the method is to be found in a Win32 DLL. These attributes are found in the System.Runtime.InteropServices namespace, and detailed documentation for these attributes is found in the .NET runtime documentation.

And here are some pages on MSDN: