Avoid undefined behavior in nearestPowerOfTwo.

The way nearestPowerOfTwo is currently defined allows for the possibility of
left-shifting an int by 32 bits or more, which is undefined behavior on
platforms where int is 32 bits, and is something that can happen here if `s`
is equal to 31 by the end of the loop. Noted by Coverity as CID 1291191.

This patch takes an algorithm to perform the same operation from Hank Warren
Jr.'s book "Hacker's Delight", which should avoid UB.

REVIEW:126540
This commit is contained in:
Michael Pyne 2015-12-28 17:08:15 -05:00
parent 4957c18a44
commit bcc36b87fb
2 changed files with 15 additions and 11 deletions

View file

@ -205,19 +205,22 @@ bool checkGLError(const char* txt)
return hasError;
}
// TODO: Drop for Plasma 6, no longer needed after OpenGL 2.0
int nearestPowerOfTwo(int x)
{
// This method had been copied from Qt's nearest_gl_texture_size()
int n = 0, last = 0;
for (int s = 0; s < 32; ++s) {
if (((x >> s) & 1) == 1) {
++n;
last = s;
}
}
if (n > 1)
return 1 << (last + 1);
return 1 << last;
unsigned y = static_cast<unsigned>(x);
// From Hank Warren's "Hacker's Delight", clp2() method.
// Works for up to 32-bit integers.
y = y - 1;
y = y | (y >> 1);
y = y | (y >> 2);
y = y | (y >> 4);
y = y | (y >> 8);
y = y | (y >> 16);
return static_cast<int>(y + 1);
}
//****************************************

View file

@ -81,6 +81,7 @@ inline bool KWINGLUTILS_EXPORT isPowerOfTwo(int x)
* @return power of two integer _greater or equal to_ x.
* E.g. nearestPowerOfTwo(513) = nearestPowerOfTwo(800) = 1024
**/
// TODO: Drop for Plasma 6, no longer needed after OpenGL 2.0
int KWINGLUTILS_EXPORT nearestPowerOfTwo(int x);
class KWINGLUTILS_EXPORT GLShader