26 #include <glog/logging.h> 29 LOG(INFO) <<
"sizeof(void*) = " <<
sizeof(
void*);
31 LOG(INFO) <<
"sizeof(std::string) = " <<
sizeof(
std::string);
32 #if defined(_LIBCPP_STRING) 33 LOG(INFO) <<
"std::string from libc++";
34 #elif defined(_STLP_STRING) 35 LOG(INFO) <<
"std::string from STLport";
36 #elif defined(_GLIBCXX_USE_FB) 37 LOG(INFO) <<
"std::string from FBString";
38 #elif defined(_GLIBCXX_STRING) && _GLIBCXX_USE_CXX11_ABI 39 LOG(INFO) <<
"std::string from libstdc++ with SSO";
40 #elif defined(_GLIBCXX_STRING) 41 LOG(INFO) <<
"std::string from old libstdc++";
42 #elif defined(_MSC_VER) 43 LOG(INFO) <<
"std::string from MSVC";
45 LOG(INFO) <<
"UNKNOWN std::string implementation";
48 LOG(INFO) <<
"sizeof(std::vector<char>) = " <<
sizeof(std::vector<char>);
49 #if defined(_LIBCPP_VECTOR) 50 LOG(INFO) <<
"std::vector from libc++";
51 #elif defined(_STLP_VECTOR) 52 LOG(INFO) <<
"std::vector from STLport";
53 #elif defined(_GLIBCXX_VECTOR) 54 LOG(INFO) <<
"std::vector from libstdc++";
55 #elif defined(_MSC_VER) 56 LOG(INFO) <<
"std::vector from MSVC";
58 LOG(INFO) <<
"UNKNOWN std::vector implementation";
64 T validData(
T const& target, std::vector<bool>
const& valid) {
67 for (std::size_t
i = 0;
i < valid.size(); ++
i) {
69 rv.push_back(target[i]);
78 std::vector<bool>& valid,
79 std::size_t newSize) {
80 auto oldSize = target.size();
83 valid.resize(newSize);
85 if (oldSize <= newSize) {
89 EXPECT_TRUE(std::equal(after.begin(), after.end(), before.begin()));
96 std::vector<bool>& valid,
99 for (
auto i = b;
i < e &&
i < target.size(); ++
i) {
100 target[
i] =
'0' + (
i % 10);
105 template <
typename T>
106 void doResize(
T& target, std::vector<bool>& valid, std::size_t newSize) {
107 auto oldSize = target.size();
109 target.resize(newSize);
110 valid.resize(newSize);
111 for (
auto i = oldSize;
i < newSize; ++
i) {
115 if (oldSize == newSize) {
117 }
else if (oldSize < newSize) {
119 EXPECT_TRUE(std::equal(before.begin(), before.end(), after.begin()));
122 EXPECT_TRUE(std::equal(after.begin(), after.end(), before.begin()));
126 template <
typename T>
127 void doClear(
T& target, std::vector<bool>& valid) {
132 template <
typename T>
133 void doInsert(
T& target, std::vector<bool>& valid, std::size_t
i) {
134 target.insert(target.begin() +
i,
'I');
135 valid.insert(valid.begin() +
i,
true);
138 template <
typename T>
139 void doErase(
T& target, std::vector<bool>& valid, std::size_t
i) {
140 target.erase(target.begin() +
i);
141 valid.erase(valid.begin() +
i);
144 template <
typename T>
146 target.push_back(
'P');
147 valid.push_back(
true);
150 template <
typename T>
152 EXPECT_LE(target.size(), target.capacity());
153 EXPECT_EQ(target.size() == 0, target.empty());
154 EXPECT_EQ(target.size(), target.end() - target.begin());
155 EXPECT_EQ(target.size(), target.cend() - target.cbegin());
156 if (!target.empty()) {
158 EXPECT_EQ(target.data(), &target.front());
159 EXPECT_EQ(target.data() + target.size() - 1, &target.back());
163 template <
typename T>
171 EXPECT_EQ(target.c_str(), target.data());
172 EXPECT_EQ(target.c_str()[target.size()],
'\0');
175 template <
typename T>
179 auto sizes = {0, 1, 10, 14, 15, 16, 17, 22, 23, 24, 32, 95, 100, 10000};
181 for (
auto j : sizes) {
184 std::vector<bool> valid;
192 std::vector<bool> valid;
201 std::vector<bool> valid;
210 std::vector<bool> valid;
220 template <
typename T>
224 auto target = folly::make_unique<T>();
225 std::vector<bool> valid;
227 for (
size_t step = 0; step < numSteps; ++step) {
233 }
else if (pct < 30) {
236 for (
size_t i = 0;
i < copy.size(); ++
i) {
238 copy[
i] = target->at(i);
243 }
else if (pct < 15) {
245 }
else if (pct < 20) {
247 }
else if (pct < 25) {
248 target = folly::make_unique<T>(
std::move(copy));
250 target = folly::make_unique<T>(
copy);
252 }
else if (pct < 35) {
254 }
else if (pct < 40) {
255 target->shrink_to_fit();
256 }
else if (pct < 45) {
258 }
else if (pct < 50) {
259 doInsert(*target, valid,
v % (target->size() + 1));
260 }
else if (pct < 55) {
261 if (!target->empty()) {
262 doErase(*target, valid,
v % target->size());
264 }
else if (pct < 60) {
266 }
else if (pct < 65) {
267 target = folly::make_unique<T>();
269 }
else if (pct < 80) {
283 TEST(UninitializedMemoryHacks, simpleString) {
284 testSimple<std::string>();
287 TEST(UninitializedMemoryHacks, simpleVectorChar) {
288 testSimple<std::vector<char>>();
291 TEST(UninitializedMemoryHacks, simpleVectorByte) {
292 testSimple<std::vector<uint8_t>>();
295 TEST(UninitializedMemoryHacks, simpleVectorInt) {
296 testSimple<std::vector<int>>();
300 testRandom<std::string>();
303 TEST(UninitializedMemoryHacks, randomVectorChar) {
304 testRandom<std::vector<char>>();
307 TEST(UninitializedMemoryHacks, randomVectorByte) {
308 testRandom<std::vector<uint8_t>>();
311 TEST(UninitializedMemoryHacks, randomVectorInt) {
312 testRandom<std::vector<int>>();
316 FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(
int)
#define EXPECT_LE(val1, val2)
void testRandom(size_t numSteps=10000)
#define EXPECT_EQ(val1, val2)
void doPushBack(T &target, std::vector< bool > &valid)
constexpr detail::Map< Move > move
void doResize(T &target, std::vector< bool > &valid, std::size_t newSize)
#define EXPECT_GE(val1, val2)
void doResizeWithoutInit(T &target, std::vector< bool > &valid, std::size_t newSize)
void doOverwrite(T &target, std::vector< bool > &valid, std::size_t b, std::size_t e)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
T validData(T const &target, std::vector< bool > const &valid)
void doClear(T &target, std::vector< bool > &valid)
void doErase(T &target, std::vector< bool > &valid, std::size_t i)
TEST(UninitializedMemoryHacks, simpleString)
void doInsert(T &target, std::vector< bool > &valid, std::size_t i)
#define EXPECT_TRUE(condition)
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
void genericCheck(T &target)
#define EXPECT_LT(val1, val2)
void randomString(String *toFill, size_t size=1000)
void resizeWithoutInitialization(std::string &s, std::size_t n)