JDK-6778657 : Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2008-12-02
  • Updated: 2012-10-08
  • Resolved: 2009-02-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u18Fixed 7Fixed hs15Fixed
Related Reports
Duplicate :  
Description
Submitted by Gary Benson

icedtea-f2i-overflow.patch - may produce results different from current.

diff -r dcb49b482348 -r f63a8dee04ae openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp
--- openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp      Mon Nov 03 14:00:57 2008 +0000
+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp      Mon Nov 03 15:56:17 2008 +0000
@@ -173,64 +173,46 @@ JRT_END


 JRT_LEAF(jint, SharedRuntime::f2i(jfloat  x))
-  if (g_isnan(x)) {return 0;}
-  jlong lltmp = (jlong)x;
-  jint ltmp   = (jint)lltmp;
-  if (ltmp == lltmp) {
-    return ltmp;
-  } else {
-    if (x < 0) {
-      return min_jint;
-    } else {
-      return max_jint;
-    }
-  }
+  if (g_isnan(x))
+    return 0;
+  if (x >= (jfloat) max_jint)
+    return max_jint;
+  if (x <= (jfloat) min_jint)
+    return min_jint;
+  return (jint) x;
 JRT_END


 JRT_LEAF(jlong, SharedRuntime::f2l(jfloat  x))
-  if (g_isnan(x)) {return 0;}
-  jlong lltmp = (jlong)x;
-  if (lltmp != min_jlong) {
-    return lltmp;
-  } else {
-    if (x < 0) {
-      return min_jlong;
-    } else {
-      return max_jlong;
-    }
-  }
+  if (g_isnan(x))
+    return 0;
+  if (x >= (jfloat) max_jlong)
+    return max_jlong;
+  if (x <= (jfloat) min_jlong)
+    return min_jlong;
+  return (jlong) x;
 JRT_END

 JRT_LEAF(jint, SharedRuntime::d2i(jdouble x))
-  if (g_isnan(x)) {return 0;}
-  jlong lltmp = (jlong)x;
-  jint ltmp   = (jint)lltmp;
-  if (ltmp == lltmp) {
-    return ltmp;
-  } else {
-    if (x < 0) {
-      return min_jint;
-    } else {
-      return max_jint;
-    }
-  }
+  if (g_isnan(x))
+    return 0;
+  if (x >= (jdouble) max_jint)
+    return max_jint;
+  if (x <= (jdouble) min_jint)
+    return min_jint;
+  return (jint) x;
 JRT_END


 JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x))
-  if (g_isnan(x)) {return 0;}
-  jlong lltmp = (jlong)x;
-  if (lltmp != min_jlong) {
-    return lltmp;
-  } else {
-    if (x < 0) {
-      return min_jlong;
-    } else {
-      return max_jlong;
-    }
-  }
+  if (g_isnan(x))
+    return 0;
+  if (x >= (jdouble) max_jlong)
+    return max_jlong;
+  if (x <= (jdouble) min_jlong)
+    return min_jlong;
+  return (jlong) x;
 JRT_END

Comments
PUBLIC COMMENTS Problem: In C++, the result of an overflowing cast to a signed integer is undefined. The functions used to implement f2i, f2l, d2i and d2l, however, rely on the assumption that the result of an overflowing cast will be the largest magnitude number with the correct sign. Solution: Replaces SharedRuntime::f2i et al with versions that should work regardless of the compiler, operating system, or CPU architecture. Added the test provided for 6779290 (closed as duplicate of this one). Reviewed by: never Contributed by: ###@###.### Fix verified (y/n): y, provided test.
23-12-2008

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/6d8fc951eb25
23-12-2008