United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6778657 Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
JDK-6778657 : Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour

Details
Type:
Bug
Submit Date:
2008-12-02
Status:
Closed
Updated Date:
2012-10-08
Project Name:
JDK
Resolved Date:
2009-02-11
Component:
hotspot
OS:
linux,generic
Sub-Component:
runtime
CPU:
x86,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs15 (b01)

Related Reports
Backport:
Backport:
Duplicate:

Sub Tasks

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
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/6d8fc951eb25
                                     
2008-12-23
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.
                                     
2008-12-23



Hardware and Software, Engineered to Work Together