Fix some signed overflow errors causing undefined behavior (in theory).
BUG=webrtc:5491
Review URL: https://codereview.webrtc.org/1744183002
Cr-Commit-Position: refs/heads/master@{#11832}
diff --git a/webrtc/base/mathutils.h b/webrtc/base/mathutils.h
index e2b2126..3c70e76 100644
--- a/webrtc/base/mathutils.h
+++ b/webrtc/base/mathutils.h
@@ -12,9 +12,28 @@
#define WEBRTC_BASE_MATHUTILS_H_
#include <math.h>
+#include <type_traits>
+
+#include "webrtc/base/checks.h"
#ifndef M_PI
#define M_PI 3.14159265359f
#endif
+// Given two numbers |x| and |y| such that x >= y, computes the difference
+// x - y without causing undefined behavior due to signed overflow.
+template <typename T>
+typename std::make_unsigned<T>::type unsigned_difference(T x, T y) {
+ static_assert(
+ std::is_signed<T>::value,
+ "Function unsigned_difference is only meaningful for signed types.");
+ RTC_DCHECK_GE(x, y);
+ typedef typename std::make_unsigned<T>::type unsigned_type;
+ // int -> unsigned conversion repeatedly adds UINT_MAX + 1 until the number
+ // can be represented as an unsigned. Since we know that the actual
+ // difference x - y can be represented as an unsigned, it is sufficient to
+ // compute the difference modulo UINT_MAX + 1, i.e using unsigned arithmetic.
+ return static_cast<unsigned_type>(x) - static_cast<unsigned_type>(y);
+}
+
#endif // WEBRTC_BASE_MATHUTILS_H_