Fix DateTime regression on ARM
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 12 Mar 2015 01:41:28 +0000 (02:41 +0100)
committerMarek Safar <marek.safar@gmail.com>
Mon, 2 May 2016 22:08:05 +0000 (00:08 +0200)
This is the same issue as in https://github.com/mono/referencesource/pull/7,
i.e. there's an overflow when casting a too large value from double->long
and the referencesource implementation relies on this being a large negative
value in order for the ArgumentOutOfRangeException to be properly thrown.

As Mono's runtime on ARM in this case returns -1, the exception isn't thrown.

The fix is to introduce an explicit overflow check, catch an eventual
OverflowException and raise the proper exception instead. This can be JIT'd
to better code than checking if the value fits into long every time.

It fixes a couple of DateTime unit tests that currently fail on ARM.

mcs/class/referencesource/mscorlib/system/datetime.cs

index c6f9af15941d1324a1b15a18528291ae5ba83409..216fe8d12a6d5c87ee9d0f9b978a684d9094e4e9 100644 (file)
@@ -348,7 +348,12 @@ namespace System {
         // Returns the DateTime resulting from adding a fractional number of
         // time units to this DateTime.
         private DateTime Add(double value, int scale) {
-            long millis = (long)(value * scale + (value >= 0? 0.5: -0.5));
+            long millis;
+            try {
+                millis = checked((long)(value * scale + (value >= 0? 0.5: -0.5)));
+            } catch (OverflowException) {
+                throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
+            }
             if (millis <= -MaxMillis || millis >= MaxMillis) 
                 throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
             return AddTicks(millis * TicksPerMillisecond);