ms csharp compiler bug

G

Guest

I am working on a c# compiler for the DynamicMethod so I try a lot of
strange things out. I came across this one:

public void CompileBug()
{
object obj = null + new object();
Console.WriteLine(obj.GetType().ToString() );
}



// IL disasm
{
// Method begins at RVA 0x111bc
// Code size 31 (0x1f)
.maxstack 2
.locals init ([0] object obj)
IL_0000: /* 00 | */ nop
IL_0001: /* 14 | */ ldnull
IL_0002: /* 73 | (0A)000024 */ newobj instance void
[mscorlib]System.Object::.ctor()
IL_0007: /* 28 | (0A)0001D0 */ call string
[mscorlib]System.String::Concat(object,

object)
IL_000c: /* 0A | */ stloc.0
IL_000d: /* 06 | */ ldloc.0
IL_000e: /* 6F | (0A)0000B4 */ callvirt instance class
[mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0013: /* 6F | (0A)00006E */ callvirt instance string
[mscorlib]System.Object::ToString()
IL_0018: /* 28 | (0A)000028 */ call void
[mscorlib]System.Console::WriteLine(string)
IL_001d: /* 00 | */ nop
IL_001e: /* 2A | */ ret
} // end of method XXX::CompileBug

I assume this should not compile at all. If I am right in my assumption
what should the error message be ? Something like "No implicit conversion
for ..." .
Is a literal null with no context considered to be of type Object (I thought
I saw that in ECMA 334).
 
G

Guest

It just occured to me that the error message should be more like "Operator
'+' cannot be applied to operands of type 'object' and 'object'" , since the
null literal would be implicitly converted to Object. Is this so.
 
A

Alvin Bruney [MVP]

it looks strange but i'd consider it a valid expression and so it should
compile and even produce a result. Why do you think it is a bug?
Mathematically, an empty set plus an object must evaluate to the object
right?

However, when I run the example, I get a system.string being printed out
with the code. Removing the null, I get a system.object. That to me implies
an inconsistency.

thoughts/comments?
--
________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
 
G

Guest

The string part is the bug. There is no implicit conversion from object to
string and besides neither operand is of type string. In a way I am not too
surprised about this bug as string does not overlode the + operator ( there
is no op_Addition method to call) the compiler (Mine anyway) has to add the
call to String::Concat .
Alvin Bruney said:
it looks strange but i'd consider it a valid expression and so it should
compile and even produce a result. Why do you think it is a bug?
Mathematically, an empty set plus an object must evaluate to the object
right?

However, when I run the example, I get a system.string being printed out
with the code. Removing the null, I get a system.object. That to me implies
an inconsistency.

thoughts/comments?
--
________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
-------------------------------------------------------


Toby Altman said:
I am working on a c# compiler for the DynamicMethod so I try a lot of
strange things out. I came across this one:

public void CompileBug()
{
object obj = null + new object();
Console.WriteLine(obj.GetType().ToString() );
}



// IL disasm
{
// Method begins at RVA 0x111bc
// Code size 31 (0x1f)
.maxstack 2
.locals init ([0] object obj)
IL_0000: /* 00 | */ nop
IL_0001: /* 14 | */ ldnull
IL_0002: /* 73 | (0A)000024 */ newobj instance void
[mscorlib]System.Object::.ctor()
IL_0007: /* 28 | (0A)0001D0 */ call string
[mscorlib]System.String::Concat(object,

object)
IL_000c: /* 0A | */ stloc.0
IL_000d: /* 06 | */ ldloc.0
IL_000e: /* 6F | (0A)0000B4 */ callvirt instance class
[mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0013: /* 6F | (0A)00006E */ callvirt instance string
[mscorlib]System.Object::ToString()
IL_0018: /* 28 | (0A)000028 */ call void
[mscorlib]System.Console::WriteLine(string)
IL_001d: /* 00 | */ nop
IL_001e: /* 2A | */ ret
} // end of method XXX::CompileBug

I assume this should not compile at all. If I am right in my assumption
what should the error message be ? Something like "No implicit conversion
for ..." .
Is a literal null with no context considered to be of type Object (I
thought
I saw that in ECMA 334).
 
G

Guest

By the way, object foo() { return new Object() + new Object(); } does not
compile (since Object does not overload the '+' operator ( or any operator).
 
B

Barry Kelly

Toby Altman said:
I am working on a c# compiler for the DynamicMethod so I try a lot of
strange things out. I came across this one:

public void CompileBug()
{
object obj = null + new object();
Console.WriteLine(obj.GetType().ToString() );
}
I assume this should not compile at all.

As you know, "+" with strings is treated specially to make string
concatenation work with objects. The relevant section is 14.7.4, the
Addition operator:

"The binary + operator performs string concatenation when one or both
operands are of type string. If an operand of string concatenation is
null, an empty string is substituted. Otherwise, any non-string operand
is converted to its string representation by invoking the virtual
ToString method inherited from type object. If ToString returns null, an
empty string is substituted."
If I am right in my assumption
what should the error message be ? Something like "No implicit conversion
for ..." .
Is a literal null with no context considered to be of type Object (I thought
I saw that in ECMA 334).

It is not. The type of the null literal is the null type (11.2.7), a
concept which only exists in the compiler - it's not in the CLR. A value
of the null type (there's only one, the "null" literal) is implicitly
convertible to any other reference type (13.1.4).

(All references to sections are from ECMA-334 3rd ed.)

-- Barry
 
B

Barry Kelly

Barry Kelly said:
As you know, "+" with strings is treated specially to make string
concatenation work with objects. The relevant section is 14.7.4, the
Addition operator:

"The binary + operator performs string concatenation when one or both
operands are of type string. If an operand of string concatenation is
null, an empty string is substituted. Otherwise, any non-string operand
is converted to its string representation by invoking the virtual
ToString method inherited from type object. If ToString returns null, an
empty string is substituted."

I omitted this: as this says, one or both operations should be of type
string. Since in your case one operand is of the null type and the other
is a value of type Object, the "+" operator shouldn't be matched.

-- Barry
 
G

Guest

Barry Kelly said:
I omitted this: as this says, one or both operations should be of type
string. Since in your case one operand is of the null type and the other
is a value of type Object, the "+" operator shouldn't be matched.

Which is pretty much what I said (... the error message should be more like
"Operator '+' cannot be applied to operands of type 'object' and 'object'
...." and thus 'object foo(){return null + new object();}' should not compile.

My compiler would try to implicitly convert null to Object and since object
is a referenc type it would ( EMCA 334 13.1.4 Implicit reference conversions
.... From the null type (§11.2.7) to any reference-type." , but would not
find a overloaded '+' operator so the error message would be something like
the above.
 
B

Barry Kelly

Toby Altman said:
Which is pretty much what I said

Sure, but now that you've got hard references to the standard, you can
log a bug.

http://connect.microsoft.com/VisualStudio/Feedback
(... the error message should be more like
"Operator '+' cannot be applied to operands of type 'object' and 'object'
..."

It should be more like "Operator '+' cannot be applied to operands of
type 'null' and 'object' ..."
My compiler would try to implicitly convert null to Object

Null is convertible to every reference type, so you must produce an
ambiguous overload error where there is a conflict between different
overload resolutions involving reference types. You can't treat null as
Object. The null type is a distinct type.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top