From 70cab78c531e298fe76a7f05045231b6615cd912 Mon Sep 17 00:00:00 2001 From: Lucian Grijincu Date: Mon, 9 May 2016 17:03:34 -0700 Subject: [PATCH] folly: ubsan: &v[0] is undefined if v.empty() Summary: before: [ RUN ] RangeFunc.Vector bits/stl_vector.h:866:9: runtime error: reference binding to null pointer of type 'int' Reviewed By: yfeldblum Differential Revision: D3279253 fbshipit-source-id: 957a8ec050f5c3b27febf7e6cd16ad1d307da169 --- folly/test/RangeTest.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index 42a76ac5..49830d7c 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -1049,6 +1049,19 @@ TEST(NonConstTest, StringPiece) { } } +// Similar to the begin() template functions, but instread of returing +// an iterator, return a pointer to data. +template +typename Container::value_type* dataPtr(Container& cont) { + // NOTE: &cont[0] is undefined if cont is empty (it creates a + // reference to nullptr - which is not dereferenced, but still UBSAN). + return cont.data(); +} +template +constexpr T* dataPtr(T (&arr)[N]) noexcept { + return &arr[0]; +} + template void testRangeFunc(C&& x, size_t n) { const auto& cx = x; @@ -1057,8 +1070,8 @@ void testRangeFunc(C&& x, size_t n) { Range r2 = range(std::forward(x)); Range r3 = range(cx); Range r5 = range(std::move(cx)); - EXPECT_EQ(r1.begin(), &x[0]); - EXPECT_EQ(r1.end(), &x[n]); + EXPECT_EQ(r1.begin(), dataPtr(x)); + EXPECT_EQ(r1.end(), dataPtr(x) + n); EXPECT_EQ(n, r1.size()); EXPECT_EQ(n, r2.size()); EXPECT_EQ(n, r3.size()); -- 2.34.1