< 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 >