Fix signed integer overflow in random indirect draw tests
authorAri Suonpaa <ari.suonpaa@siru.fi>
Wed, 25 May 2022 12:11:11 +0000 (15:11 +0300)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Thu, 9 Jun 2022 16:42:46 +0000 (16:42 +0000)
VK-GL-CTS Issue: 3331

Affects:

dEQP-GLES31.functional.draw_indirect.random.*

Components: OpenGL ES
Change-Id: I75a57a0ee14f00d049e0c27628017c86b7078174

modules/glshared/glsDrawTest.cpp

index b8cff9c..a383409 100644 (file)
@@ -431,9 +431,39 @@ public:
        typedef WrappedType<float>              Float;
        typedef WrappedType<double>             Double;
 
-       typedef WrappedType<deInt32>    Int;
        typedef WrappedType<deUint32>   Uint;
 
+       // All operations are calculated using 64bit values to avoid signed integer overflow which is undefined.
+       class Int
+       {
+       public:
+               static Int              create                          (deInt32 value)                         { Int v; v.m_value = value; return v; }
+               inline deInt32  getValue                        (void) const                            { return m_value; }
+
+               inline Int              operator+                       (const Int& other) const        { return Int::create((deInt32)((deInt64)m_value + (deInt64)other.getValue())); }
+               inline Int              operator*                       (const Int& other) const        { return Int::create((deInt32)((deInt64)m_value * (deInt64)other.getValue())); }
+               inline Int              operator/                       (const Int& other) const        { return Int::create((deInt32)((deInt64)m_value / (deInt64)other.getValue())); }
+               inline Int              operator-                       (const Int& other) const        { return Int::create((deInt32)((deInt64)m_value - (deInt64)other.getValue())); }
+
+               inline Int&             operator+=                      (const Int& other)                      { m_value = (deInt32)((deInt64)m_value + (deInt64)other.getValue()); return *this; }
+               inline Int&             operator*=                      (const Int& other)                      { m_value = (deInt32)((deInt64)m_value * (deInt64)other.getValue()); return *this; }
+               inline Int&             operator/=                      (const Int& other)                      { m_value = (deInt32)((deInt64)m_value / (deInt64)other.getValue()); return *this; }
+               inline Int&             operator-=                      (const Int& other)                      { m_value = (deInt32)((deInt64)m_value - (deInt64)other.getValue()); return *this; }
+
+               inline bool             operator==                      (const Int& other) const        { return m_value == other.m_value; }
+               inline bool             operator!=                      (const Int& other) const        { return m_value != other.m_value; }
+               inline bool             operator<                       (const Int& other) const        { return m_value < other.m_value; }
+               inline bool             operator>                       (const Int& other) const        { return m_value > other.m_value; }
+               inline bool             operator<=                      (const Int& other) const        { return m_value <= other.m_value; }
+               inline bool             operator>=                      (const Int& other) const        { return m_value >= other.m_value; }
+
+               inline                  operator deInt32        (void) const                            { return m_value; }
+               template<class T>
+               inline T                to                                      (void) const                            { return (T)m_value; }
+       private:
+               deInt32 m_value;
+       };
+
        class Half
        {
        public: