Bugzilla – Bug 312040
TimeSpan.MinValue.Negate () does not throw
Last modified: 2007-09-15 21:24:23 UTC
---- Reported by ndrochak@gol.com 2003-02-25 09:06:36 MST ---- The following simple test does not throw an exception like it should: using System; namespace N { public class X { public static void Main() { TimeSpan t1 = TimeSpan.MinValue.Negate (); } } } ---- Additional Comments From ndrochak@gol.com 2003-02-26 00:28:18 MST ---- We need to control the error message displayed with the exception anyway, so maybe 'checked' isn't the best way to do it. Here's attached a proposed patch for this bug. OK to commit? Index: TimeSpan.cs =================================================================== RCS file: /cvs/public/mcs/class/corlib/System/TimeSpan.cs,v retrieving revision 1.8 diff -u -r1.8 TimeSpan.cs --- TimeSpan.cs 20 Jun 2002 12:06:21 -0000 1.8 +++ TimeSpan.cs 26 Feb 2003 05:28:05 -0000 @@ -266,9 +266,9 @@ public TimeSpan Negate () { - checked { - return new TimeSpan (-_ticks); - } + if (_ticks == long.MinValue) + throw new OverflowException ("This TimeSpan value is MinValue and cannot be negated.") + return new TimeSpan (-_ticks); } public static TimeSpan Parse (string s) ---- Additional Comments From ndrochak@gol.com 2003-03-06 08:02:32 MST ---- Patching TimeSpan.cs to "work around" this potential mcs or runtime bug, not sure which. We need the error message in the exception anyway. Leaving open but moving it to mcs to have someone look at it. There was a bug in mcs ith checked byte values before, wasn't there? ---- Additional Comments From miguel@ximian.com 2003-04-01 18:01:03 MST ---- I tried running the program with mcs, and it does thrown an exception. What was the MCS bug? ---- Additional Comments From gonzalo@ximian.com 2003-04-01 22:13:27 MST ---- You should undo Nick's workaround in TimeSpan.Negate, which is already in CVS. ---- Additional Comments From miguel@ximian.com 2003-07-24 11:19:53 MST ---- Can we get a simple test case for this bug? ---- Additional Comments From gonzalo@ximian.com 2003-07-24 12:15:53 MST ---- Here it is: --------------- using System; class Test { static void Main () { long l = long.MinValue; long k; checked { k = -l; } Console.WriteLine (l); Console.WriteLine (k); } } ---------- Under MS runtime, it throws an OverflowException. Under mono runtime, it prints: -9223372036854775808 -9223372036854775808 ---- Additional Comments From bmaurer@users.sf.net 2003-12-23 21:37:39 MST ---- Ok, so on MCS we emit IL_0000: ldc.i8 0x8000000000000000 IL_0009: stloc.0 IL_000a: ldloc.0 IL_000b: neg IL_000c: stloc.1 IL_000d: ldloc.0 IL_000e: call void [mscorlib]System.Console::WriteLine (int64) IL_0013: ldloc.1 IL_0014: call void [mscorlib]System.Console::WriteLine (int64) IL_0019: ret CSC emits IL_0000: ldc.i8 0x8000000000000000 IL_0009: stloc.0 IL_000a: ldc.i4.0 IL_000b: conv.i8 IL_000c: ldloc.0 IL_000d: sub.ovf IL_000e: stloc.1 IL_000f: ldloc.0 IL_0010: call void [mscorlib]System.Console::WriteLine (int64) IL_0015: ldloc.1 IL_0016: call void [mscorlib]System.Console::WriteLine (int64) IL_001b: ret ---- Additional Comments From bmaurer@users.sf.net 2003-12-23 21:57:02 MST ---- According to Partition III, 3.50; Negation of integral values is standard twos complement negation. In particular, negating the most negative number (which does not have a positive counterpart) yields the most negative number. To detect this overflow use the sub.ovf instruction instead (i.e. subtract from 0). ---- Additional Comments From bmaurer@users.sf.net 2003-12-23 22:24:55 MST ---- Created an attachment (id=164563) This should fix it ---- Additional Comments From bmaurer@users.sf.net 2003-12-23 22:25:38 MST ---- The above patch resolves this issue in both the long and the int case. We are now emitting the same code as csc. ---- Additional Comments From miguel@ximian.com 2003-12-25 17:05:50 MST ---- Please feel free to apply this patch. ---- Additional Comments From bmaurer@users.sf.net 2003-12-25 17:14:32 MST ---- Fixed in CVS. Imported an attachment (id=164563)