From c2921abe4a5aed3844622ca212c32c035c8b2e0b Mon Sep 17 00:00:00 2001
From: hendricks266 <hendricks266@1a8010ca-5511-0410-912e-c29ae57300e0>
Date: Mon, 8 Apr 2019 06:27:48 +0000
Subject: [PATCH] SW: Address -Woverflow warnings resulting from the struct
 tracker templates being too restrictive

git-svn-id: https://svn.eduke32.com/eduke32@7526 1a8010ca-5511-0410-912e-c29ae57300e0
---
 source/build/include/compat.h             | 58 ++++++++++++++++++++---
 source/build/include/tracker.hpp          | 34 +++++++------
 source/build/include/tracker_operator.hpp | 13 ++---
 3 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/source/build/include/compat.h b/source/build/include/compat.h
index a49e2c5b5..8e4774b09 100644
--- a/source/build/include/compat.h
+++ b/source/build/include/compat.h
@@ -233,6 +233,16 @@
 # define ASMSYM(x) x
 #endif
 
+#if defined __cplusplus
+# define STATIC_CAST_OP(t) static_cast<t>
+# define REINTERPRET_CAST_OP(t) reinterpret_cast<t>
+#else
+# define STATIC_CAST_OP(t) (t)
+# define REINTERPRET_CAST_OP(t) (t)
+#endif
+#define STATIC_CAST(t, v) (STATIC_CAST_OP(t)(v))
+#define REINTERPRET_CAST(t, v) (REINTERPRET_CAST_OP(t)(v))
+
 #if defined __cplusplus && (__cplusplus >= 201103L || __has_feature(cxx_constexpr) || EDUKE32_MSVC_PREREQ(1900))
 # define HAVE_CONSTEXPR
 # define CONSTEXPR constexpr
@@ -913,14 +923,13 @@ static FORCE_INLINE void *Baligned_alloc(const size_t alignment, const size_t si
 
 ////////// Data serialization //////////
 
-static FORCE_INLINE CONSTEXPR uint16_t B_SWAP16(uint16_t value)
+static FORCE_INLINE CONSTEXPR uint16_t B_SWAP16_impl(uint16_t value)
 {
     return
         ((value & 0xFF00u) >> 8u) |
         ((value & 0x00FFu) << 8u);
 }
-
-static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32(uint32_t value)
+static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32_impl(uint32_t value)
 {
     return
         ((value & 0xFF000000u) >> 24u) |
@@ -928,8 +937,7 @@ static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32(uint32_t value)
         ((value & 0x0000FF00u) <<  8u) |
         ((value & 0x000000FFu) << 24u);
 }
-
-static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64(uint64_t value)
+static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64_impl(uint64_t value)
 {
     return
       ((value & 0xFF00000000000000ULL) >> 56ULL) |
@@ -942,10 +950,48 @@ static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64(uint64_t value)
       ((value & 0x00000000000000FFULL) << 56ULL);
 }
 
-// The purpose of these functions, as opposed to macros, is to prevent them from being used as lvalues.
+/* The purpose of B_PASS* as functions, as opposed to macros, is to prevent them from being used as lvalues. */
+#if CXXSTD >= 2011
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int16_t, uint16_t> B_SWAP16(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int16_t, uint16_t> >(B_SWAP16_impl(static_cast<uint16_t>(x)));
+}
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int32_t, uint32_t> B_SWAP32(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int32_t, uint32_t> >(B_SWAP32_impl(static_cast<uint32_t>(x)));
+}
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int64_t, uint64_t> B_SWAP64(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int64_t, uint64_t> >(B_SWAP64_impl(static_cast<uint64_t>(x)));
+}
+
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int16_t, uint16_t> B_PASS16(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int16_t, uint16_t> >(x);
+}
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int32_t, uint32_t> B_PASS32(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int32_t, uint32_t> >(x);
+}
+template <typename T>
+static FORCE_INLINE CONSTEXPR conditional_t<is_signed<T>::value, int64_t, uint64_t> B_PASS64(T x)
+{
+    return static_cast< conditional_t<is_signed<T>::value, int64_t, uint64_t> >(x);
+}
+#else
+#define B_SWAP16(x) B_SWAP16_impl(x)
+#define B_SWAP32(x) B_SWAP32_impl(x)
+#define B_SWAP64(x) B_SWAP64_impl(x)
+
 static FORCE_INLINE CONSTEXPR uint16_t B_PASS16(uint16_t const x) { return x; }
 static FORCE_INLINE CONSTEXPR uint32_t B_PASS32(uint32_t const x) { return x; }
 static FORCE_INLINE CONSTEXPR uint64_t B_PASS64(uint64_t const x) { return x; }
+#endif
 
 #if B_LITTLE_ENDIAN == 1
 # define B_LITTLE64(x) B_PASS64(x)
diff --git a/source/build/include/tracker.hpp b/source/build/include/tracker.hpp
index 10080d003..1b4d4d2a9 100644
--- a/source/build/include/tracker.hpp
+++ b/source/build/include/tracker.hpp
@@ -36,25 +36,35 @@ class TRACKER_NAME_
             return this->TrackedValue--;
         }
 
-        inline TrackedType operator = (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator = (RightHandType);
 
-        inline TrackedType operator += (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator += (RightHandType);
 
-        inline TrackedType operator -= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator -= (RightHandType);
 
-        inline TrackedType operator *= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator *= (RightHandType);
 
-        inline TrackedType operator /= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator /= (RightHandType);
 
-        inline TrackedType operator |= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator |= (RightHandType);
 
-        inline TrackedType operator &= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator &= (RightHandType);
 
-        inline TrackedType operator ^= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator ^= (RightHandType);
 
-        inline TrackedType operator <<= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator <<= (RightHandType);
 
-        inline TrackedType operator >>= (TrackedType);
+        template <typename RightHandType>
+        inline TrackedType operator >>= (RightHandType);
 
         inline operator TrackedType() const;
 
@@ -73,11 +83,7 @@ enum {
 
 #endif
 
-#define __TRACKER_RIGHTHAND_TYPE TrackedType rightHand
-#define __TRACKER_RIGHTHAND rightHand
 #include "tracker_operators.hpp"
-#undef __TRACKER_RIGHTHAND_TYPE
-#undef __TRACKER_RIGHTHAND
 
 template<typename TrackedType>
 inline TRACKER_NAME_<TrackedType>::operator TrackedType() const
diff --git a/source/build/include/tracker_operator.hpp b/source/build/include/tracker_operator.hpp
index 4efbf5746..b9b6f9e89 100644
--- a/source/build/include/tracker_operator.hpp
+++ b/source/build/include/tracker_operator.hpp
@@ -1,14 +1,15 @@
 
-template<typename TrackedType>
-inline TrackedType TRACKER_NAME_<TrackedType>::operator TRACKER_OPERATOR_ (__TRACKER_RIGHTHAND_TYPE)
+template <typename TrackedType>
+template <typename RightHandType>
+inline TrackedType TRACKER_NAME_<TrackedType>::operator TRACKER_OPERATOR_ (RightHandType rightHand)
 {
     bool isNoop = false;
 
     switch (TRACKER_NOOP_)
     {
-        case TRACKER_NOOP_RIGHTHAND_EQUAL_: isNoop = (this->TrackedValue == __TRACKER_RIGHTHAND); break;
-        case TRACKER_NOOP_RIGHTHAND_ZERO_: isNoop  = (__TRACKER_RIGHTHAND == 0); break;
-        case TRACKER_NOOP_RIGHTHAND_ONE_: isNoop   = (__TRACKER_RIGHTHAND == 1);
+        case TRACKER_NOOP_RIGHTHAND_EQUAL_: isNoop = (this->TrackedValue == rightHand); break;
+        case TRACKER_NOOP_RIGHTHAND_ZERO_: isNoop  = (rightHand == 0); break;
+        case TRACKER_NOOP_RIGHTHAND_ONE_: isNoop   = (rightHand == 1);
             fallthrough__;
         // case __TRACKER_NEVER:
         default:
@@ -18,7 +19,7 @@ inline TrackedType TRACKER_NAME_<TrackedType>::operator TRACKER_OPERATOR_ (__TRA
     if (!isNoop)
     {
         TRACKER_GLOBAL_HOOK_((uintptr_t) & this->TrackedValue);
-        return this->TrackedValue TRACKER_OPERATOR_ __TRACKER_RIGHTHAND;
+        return this->TrackedValue TRACKER_OPERATOR_ rightHand;
     }
     else return this->TrackedValue;
 }