< prev index next >

src/hotspot/share/runtime/atomic.hpp

Print this page

        

@@ -519,16 +519,20 @@
 
 template<typename I, typename D>
 inline D Atomic::sub(I sub_value, D volatile* dest) {
   STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
   STATIC_ASSERT(IsIntegral<I>::value);
-  typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type AddendType;
+  // If D is a pointer type, use [u]intptr_t as the addend type,
+  // matching signedness of I.  Otherwise, use D as the addend type.
+  typedef typename Conditional<IsSigned<I>::value, intptr_t, uintptr_t>::type PI;
+  typedef typename Conditional<IsPointer<D>::value, PI, D>::type AddendType;
+  // Only allow conversions that can't change the value.
+  STATIC_ASSERT(IsSigned<I>::value == IsSigned<AddendType>::value); 
+  STATIC_ASSERT(sizeof(I) <= sizeof(AddendType));
   AddendType addend = sub_value;
-  STATIC_ASSERT((IsIntegral<D>::value && IsSigned<I>::value == IsSigned<AddendType>::value) ||
-                IsPointer<D>::value);
   // Assumes two's complement integer representation.
-  #pragma warning(suppress: 4146)
+  #pragma warning(suppress: 4146) // In case AddendType is not signed.
   return Atomic::add(-addend, dest);
 }
 
 // Define the class before including platform file, which may specialize
 // the operator definition.  No generic definition of specializations
< prev index next >