Bugzilla – Bug 313498
[PATCH] We generate invalid code for using idisposable structs
Last modified: 2007-09-15 21:24:23 UTC
---- Reported by bmaurer@users.sf.net 2004-01-04 23:45:45 MST ---- using System; struct Blah : System.IDisposable { public void Dispose () { Console.WriteLine ("foo"); } } class B { static void Main () { using (Blah b = new Blah ()) { Console.WriteLine ("..."); } } } When compiled and run on Mono we get, ** ERROR **: Invalid IL code at IL001d in .B:Main (): IL_001d: ldloc.0 The IL in question is: IL_0017: ldloc.0 IL_0018: brfalse IL_0023 IL_001d: ldloc.0 IL_001e: callvirt instance void class [mscorlib]'System.IDisposable'::'Dispose'() IL_0023: endfinally MS generates: IL_0014: ldloca.s V_0 IL_0016: call instance void Blah::Dispose() IL_001b: endfinally ---- Additional Comments From bmaurer@users.sf.net 2004-01-04 23:53:22 MST ---- Related, using System; using System.Collections; struct Blah : IEnumerable { IEnumerator IEnumerable.GetEnumerator () { return null; } } class B { static void Main () { foreach (object o in new Blah ()) ; } } Makes the runtime freeze. It makes the MS runtime throw an ExecutionEngineExceptioon. The IL is invalid, again we treat it like a reference type. We need a few test cases 1) IDisposable struct -- regular impl, explicit impl 2) IEnumerable struct -- regulare / explicit impl 3) IEnumerable returning a strongly typed struct -- regular/explicit ---- Additional Comments From pcgod@gmx.net 2004-01-05 01:58:20 MST ---- Created an attachment (id=165420) proposed patch which fixes the first testcase ---- Additional Comments From bmaurer@users.sf.net 2004-01-05 07:57:31 MST ---- Hmmm, this looks like it could cause regressions (if the object is not idisposable, it looks like it might thow an exception). Did it pass all of mcs/tests? If we do not have tests for what we are currently able to do, we need to write those first, and then do the fix, so we dont regress anything. ---- Additional Comments From pcgod@gmx.net 2004-01-05 16:20:25 MST ---- Created an attachment (id=165421) new patch which passes the tests ---- Additional Comments From bmaurer@users.sf.net 2004-01-05 16:35:54 MST ---- THis does not handle the case where the ValueType does not inherit IDisposable. Also, we do not handle the case where it does inherit IDisposable, but only as an explicit impl. You do not handle if there are multiple overloads for Dispose You should not emit a callvirt on a struct ---- Additional Comments From pcgod@gmx.net 2004-01-05 18:55:29 MST ---- Created an attachment (id=165422) new patch which fixes the issues of the last patch ---- Additional Comments From miguel@ximian.com 2004-01-07 00:36:48 MST ---- Fantastic job once again guys. I have now applied this patch. ---- Additional Comments From bmaurer@users.sf.net 2004-01-07 00:59:22 MST ---- Miguel, this only covers the using case. The IEnumerator one is not fixed (same problem, different section of code). ---- Additional Comments From pcgod@gmx.net 2004-01-07 15:08:27 MST ---- Created an attachment (id=165423) patch for the second problem ---- Additional Comments From martin@ximian.com 2004-04-29 13:19:07 MST ---- Fixed in CVS. Imported an attachment (id=165420) Imported an attachment (id=165421) Imported an attachment (id=165422) Imported an attachment (id=165423) Unknown operating system unknown. Setting to default OS "Other".