Bug 312040 (MONO38674) - TimeSpan.MinValue.Negate () does not throw
Summary: TimeSpan.MinValue.Negate () does not throw
Status: RESOLVED FIXED
Alias: MONO38674
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: unspecified
Hardware: Other Red Hat 8.0
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Ben Maurer
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2003-02-25 16:06 UTC by Nick D
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
This should fix it (776 bytes, patch)
2003-12-24 05:24 UTC, Thomas Wiest
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 18:07:03 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)