Merge pull request #4320 from yandex/bitmask-ubsan

Fixed error found by UBSan; added a test for bitmask functions for negative input
This commit is contained in:
alexey-milovidov 2019-02-10 01:27:04 +03:00 committed by GitHub
commit 77ce3dab0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 10 deletions

View File

@ -21,8 +21,8 @@
#include <Functions/FunctionHelpers.h>
#include <arpa/inet.h>
#include <ext/range.h>
#include <type_traits>
#include <array>
@ -1260,6 +1260,8 @@ public:
template <typename T>
bool tryExecute(const IColumn * column, ColumnPtr & out_column)
{
using UnsignedT = std::make_unsigned_t<T>;
if (const ColumnVector<T> * col_from = checkAndGetColumn<ColumnVector<T>>(column))
{
auto col_values = ColumnVector<T>::create();
@ -1275,11 +1277,11 @@ public:
for (size_t row = 0; row < size; ++row)
{
T x = vec_from[row];
UnsignedT x = vec_from[row];
while (x)
{
T y = (x & (x - 1));
T bit = x ^ y;
UnsignedT y = x & (x - 1);
UnsignedT bit = x ^ y;
x = y;
res_values.push_back(bit);
}

View File

@ -9,6 +9,7 @@
#include <IO/WriteHelpers.h>
#include <Common/formatReadable.h>
#include <Common/typeid_cast.h>
#include <type_traits>
namespace DB
@ -73,16 +74,19 @@ private:
template <typename T>
inline static void writeBitmask(T x, WriteBuffer & out)
{
using UnsignedT = std::make_unsigned_t<T>;
UnsignedT u_x = x;
bool first = true;
while (x)
while (u_x)
{
T y = (x & (x - 1));
T bit = x ^ y;
x = y;
UnsignedT y = u_x & (u_x - 1);
UnsignedT bit = u_x ^ y;
u_x = y;
if (!first)
out.write(",", 1);
writeChar(',', out);
first = false;
writeIntText(bit, out);
writeIntText(T(bit), out);
}
}

View File

@ -0,0 +1,16 @@
[]
1,2,4
[1,2,4]
1,2,4,8,16,32,64,-128
[1,2,4,8,16,32,64,-128]
-128
[-128]
[]
1,2,4
[1,2,4]
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,-9223372036854775808
[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,-9223372036854775808]
128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,-9223372036854775808
[128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,-9223372036854775808]

View File

@ -0,0 +1,17 @@
SELECT bitmaskToList(0);
SELECT bitmaskToArray(0);
SELECT bitmaskToList(7);
SELECT bitmaskToArray(7);
SELECT bitmaskToList(-1);
SELECT bitmaskToArray(-1);
SELECT bitmaskToList(-128);
SELECT bitmaskToArray(-128);
SELECT bitmaskToList(toInt64(0));
SELECT bitmaskToArray(toInt64(0));
SELECT bitmaskToList(toInt64(7));
SELECT bitmaskToArray(toInt64(7));
SELECT bitmaskToList(toInt64(-1));
SELECT bitmaskToArray(toInt64(-1));
SELECT bitmaskToList(toInt64(-128));
SELECT bitmaskToArray(toInt64(-128));