Fix signed integer overflow in shader operator tests
authorAri Suonpaa <ari.suonpaa@siru.fi>
Mon, 13 Dec 2021 09:20:41 +0000 (11:20 +0200)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Thu, 6 Jan 2022 22:46:32 +0000 (22:46 +0000)
32bit integer reference value calculation had possible
signed integer overflows which are undefined. Now the
references are calculated using 64bit integers.

VK-GL-CTS Issue: 3335

Affects:

dEQP-GLES3.functional.shaders.operator.binary_operator.*

Components: OpenGL ES
Change-Id: I18e5eec98a7b93375c075a833bdf68534353c634

modules/gles3/functional/es3fShaderOperatorTests.cpp

index c71eea4..4bc1ebe 100644 (file)
@@ -178,6 +178,53 @@ template<typename T> inline T selection    (bool cond, T a, T b)   { return cond ? a
 template<int Size>                             inline Vector<deUint32, Size>   subVecScalar                    (const Vector<deUint32, Size>& v, deUint32 s)   { return (v.asInt() - (int)s).asUint(); };
 
 template<typename T, int Size> inline Vector<T, Size>                  addVecScalar                    (const Vector<T, Size>& v, T s)                                 { return v + s; };
+
+// Specialize add, sub, and mul integer operations to use 64bit to avoid undefined signed integer overflows.
+inline int add                 (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) + static_cast<deInt64>(b)); }
+inline int sub                 (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) - static_cast<deInt64>(b)); }
+inline int mul                 (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) * static_cast<deInt64>(b)); }
+
+inline deUint32 add            (deUint32 a, deUint32 b) { return a + b; }
+inline deUint32 sub            (deUint32 a, deUint32 b) { return a - b; }
+inline deUint32 mul            (deUint32 a, deUint32 b) { return a * b; }
+
+#define DECLARE_IVEC_BINARY_FUNC(OP_NAME)      \
+template <int Size> inline Vector<int, Size> OP_NAME (const Vector<int, Size>& a, const Vector<int, Size>& b)  \
+{                                                                                                                      \
+       Vector<int, Size> res;                                                                  \
+       for (int i = 0; i < Size; i++)                                                  \
+               res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i]);      \
+       return res;                                                                                             \
+}
+
+#define DECLARE_IVEC_INT_BINARY_FUNC(OP_NAME) \
+template<int Size> inline Vector<int, Size> OP_NAME##VecScalar (const Vector<int, Size>& v, int s) \
+{                                                                                      \
+       Vector<int, Size> ret;                                  \
+       for (int i = 0; i < Size; i++)                  \
+               ret[i] = OP_NAME(v.m_data[i], s);       \
+       return ret;                                                             \
+};
+
+#define DECLARE_INT_IVEC_BINARY_FUNC(OP_NAME) \
+template<int Size> inline Vector<int, Size> OP_NAME##ScalarVec (int s, const Vector<int, Size>& v) \
+{                                                                                      \
+       Vector<int, Size> ret;                                  \
+       for (int i = 0; i < Size; i++)                  \
+               ret[i] = OP_NAME(s, v.m_data[i]);       \
+       return ret;                                                             \
+};
+
+DECLARE_IVEC_BINARY_FUNC(add)
+DECLARE_IVEC_BINARY_FUNC(sub)
+DECLARE_IVEC_BINARY_FUNC(mul)
+DECLARE_IVEC_INT_BINARY_FUNC(add)
+DECLARE_IVEC_INT_BINARY_FUNC(sub)
+DECLARE_IVEC_INT_BINARY_FUNC(mul)
+DECLARE_INT_IVEC_BINARY_FUNC(add)
+DECLARE_INT_IVEC_BINARY_FUNC(sub)
+DECLARE_INT_IVEC_BINARY_FUNC(mul)
+
 template<typename T, int Size> inline Vector<T, Size>                  subVecScalar                    (const Vector<T, Size>& v, T s)                                 { return v - s; };
 template<typename T, int Size> inline Vector<T, Size>                  mulVecScalar                    (const Vector<T, Size>& v, T s)                                 { return v * s; };
 template<typename T, int Size> inline Vector<T, Size>                  divVecScalar                    (const Vector<T, Size>& v, T s)                                 { return v / s; };