Bug 12608 - /usr/bin/mcs: Wrong IL generated for struct + implicit string cast + null comparison
Summary: /usr/bin/mcs: Wrong IL generated for struct + implicit string cast + null com...
Alias: None
Product: Compilers
Classification: Mono
Component: C# ()
Version: unspecified
Hardware: PC All
: --- normal
Target Milestone: ---
Assignee: Marek Safar
Depends on:
Reported: 2013-06-08 21:31 UTC by Bruce Weirdan
Modified: 2013-06-25 08:15 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Test case to demostrate the problem (805 bytes, text/plain)
2013-06-08 21:32 UTC, Bruce Weirdan

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Bruce Weirdan 2013-06-08 21:31:33 UTC
It seems mcs generates IL that simply does not make sense (and differs
to what Visual Studio generates) for the following source code:

using System;

namespace PHP
        public struct FullPath
                private string path;

                public FullPath(string arbitraryPath)
                        this.path = arbitraryPath;

                public static implicit operator string(FullPath fullPath)
                        return fullPath.path;

        class FullPathTest
                public static void Main (string[] args)

                        FullPath fp = new FullPath ("/etc/passwd");

                        Console.WriteLine ("Comparing with == : " + (fp == null ? "true" : "false") + "; expected: false");
                        Console.WriteLine ("Comparing with != : " + (fp != null ? "true" : "false") + "; expected: true");
                        Console.WriteLine ();

Here's a snippet of monodis output for assembly generated with mono compiler (ACTUAL):

        IL_000c:  ldstr "Comparing with == : "
        IL_0011:  ldloc.0
        IL_0012:  call string valuetype PHP.FullPath::op_Implicit(valuetype PHP.FullPath)
        IL_0017:  ldloc.0   // should be ldnull (!)
        IL_0018:  call string valuetype PHP.FullPath::op_Implicit(valuetype PHP.FullPath)  // this line should not be present at all
        IL_001d:  call bool string::op_Equality(string, string)
        IL_0022:  brfalse IL_0031

        IL_0027:  ldstr "true"
        IL_002c:  br IL_0036

        IL_0031:  ldstr "false"
        IL_0036:  ldstr "; expected: false"
        IL_003b:  call string string::Concat(string, string, string)
        IL_0040:  call void class [mscorlib]System.Console::WriteLine(string)

Here's what Visual Studio 2012 Express generates (EXPECTED):

        IL_000e:  ldstr "Comparing with == : "
        IL_0013:  ldloc.0
        IL_0014:  call string valuetype PHP.FullPath::op_Implicit(valuetype PHP.FullPath)
        IL_0019:  ldnull
        IL_001a:  call bool string::op_Equality(string, string)
        IL_001f:  brtrue.s IL_0028

        IL_0021:  ldstr "false"
        IL_0026:  br.s IL_002d

        IL_0028:  ldstr "true"
        IL_002d:  nop
        IL_002e:  ldstr "; expected: false"
        IL_0033:  call string string::Concat(string, string, string)
        IL_0038:  call void class [mscorlib]System.Console::WriteLine(string)

As a result of this, program compiled with mono csharp compiler produces
totally unexpected results.

Actual program output: 
Comparing with == : true; expected: false
Comparing with != : false; expected: true

Expected output:
Comparing with == : false; expected: false
Comparing with != : true; expected: true

-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 3.8-2-686-pae (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages mono-mcs depends on:
ii  libc6                            2.17-3
ii  libmono-corlib4.5-cil            3.0.6+dfsg2-4
ii  libmono-microsoft-csharp4.0-cil  3.0.6+dfsg2-4
ii  libmono-system-core4.0-cil       3.0.6+dfsg2-4
ii  libmono-system-xml4.0-cil        3.0.6+dfsg2-4
ii  libmono-system4.0-cil            3.0.6+dfsg2-4
ii  mono-runtime                     3.0.6+dfsg2-4

Versions of packages mono-mcs recommends:
ii  pkg-config  0.26-1

mono-mcs suggests no packages.

-- no debconf information

Also replicated with Mono 3.0.10 on Windows
Comment 1 Bruce Weirdan 2013-06-08 21:32:57 UTC
Created attachment 4089 [details]
Test case to demostrate the problem
Comment 2 Marek Safar 2013-06-25 08:15:43 UTC
Fixed in master