Skip to content

Commit 380c005

Browse files
yfeldblumfacebook-github-bot
authored andcommitted
suppress warning array-bounds in F14Table
Summary: There are two cases: * In `F14Chunk::item()`, it is a contractual requirement on the caller that the this instance is not any global empty-instance, i.e., is a real `F14Chunk` and is not actually any `F14EmptyTagVector`. GCC does not know this requirement and diagnoses a possible violation of `array-bounds`, so we teach GCC to understand this requirement. * In `prefetchAddr`, it is intentional that a wild address may be prefetched. This allows the find operation to avoid extra loads and branches that would slow it down, just to issue prefetches intended to speed it up. In C++, accesses via wild addresses are forbidden. But on every architecture, prefetches of wild addresses are permitted. GCC diagnoses a poossible violation of `array-bounds`, so we suppress. Addresses violations of warning `array-bounds` following these patterns: ``` In file included from folly/folly/container/detail/F14Policy.h:29, from folly/container/F14Map.h:41, from folly/container/test/F14MapTest.cpp:17: In function ‘void folly::f14::detail::prefetchAddr(const T*) [with T = std::pair<const folly::test::Tracked<1>, int>]’, inlined from ‘folly::f14::detail::F14Table<Policy>::ItemIter folly::f14::detail::F14Table<Policy>::findImpl(HashPair, const K&, Prefetch) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/detail/F14Table.h:1575:21, inlined from ‘folly::f14::detail::F14Table<Policy>::ItemIter folly::f14::detail::F14Table<Policy>::find(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/detail/F14Table.h:1627:20, inlined from ‘folly::f14::detail::F14BasicMap<Policy>::EnableHeterogeneousFind<K, bool> folly::f14::detail::F14BasicMap<Policy>::contains(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/F14Map.h:931:24, inlined from ‘folly::f14::detail::F14BasicMap<Policy>::EnableHeterogeneousFind<K, long unsigned int> folly::f14::detail::F14BasicMap<Policy>::count(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/F14Map.h:789:20, inlined from ‘void runHeterogeneousInsertTest() [with M = folly::F14FastMap<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1> >]’ at folly/container/test/F14MapTest.cpp:1800:3: folly/container/detail/F14Table.h:461:21: warning: array subscript 9 is outside array bounds of ‘const folly::f14::detail::F14EmptyTagVector [1]’ [-Warray-bounds=] 461 | __builtin_prefetch(static_cast<void const*>(ptr)); | ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ folly/container/detail/F14Table.h: In function ‘void runHeterogeneousInsertTest() [with M = folly::F14FastMap<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1> >]’: folly/container/detail/F14Table.h:490:38: note: at offset 144 into object ‘instance’ of size 16 490 | static constexpr F14EmptyTagVector instance; | ^~~~~~~~ ``` ``` In file included from /opt/rh/gcc-toolset-13/root/usr/include/c++/13/functional:65, from folly/lang/Exception.h:21, from folly/Range.h:43, from folly/container/F14Map.h:33: In member function ‘constexpr const std::array<_Tp, _Nm>::value_type& std::array<_Tp, _Nm>::operator[](size_type) const [with _Tp = std::aligned_storage<16, 8>::type; long unsigned int _Nm = 15]’, inlined from ‘folly::f14::detail::F14Chunk<ItemType>::Item* folly::f14::detail::F14Chunk<ItemType>::itemAddr(std::size_t) const [with ItemType = std::pair<const folly::test::Tracked<1>, int>]’ at folly/container/detail/F14Table.h:750:62, inlined from ‘folly::f14::detail::F14Chunk<ItemType>::Item& folly::f14::detail::F14Chunk<ItemType>::item(std::size_t) [with ItemType = std::pair<const folly::test::Tracked<1>, int>]’ at folly/container/detail/F14Table.h:755:25, inlined from ‘folly::f14::detail::F14Table<Policy>::ItemIter folly::f14::detail::F14Table<Policy>::findImpl(HashPair, const K&, Prefetch) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/detail/F14Table.h:1580:13, inlined from ‘folly::f14::detail::F14Table<Policy>::ItemIter folly::f14::detail::F14Table<Policy>::find(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/detail/F14Table.h:1627:20, inlined from ‘folly::f14::detail::F14BasicMap<Policy>::EnableHeterogeneousFind<K, bool> folly::f14::detail::F14BasicMap<Policy>::contains(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/F14Map.h:931:24, inlined from ‘folly::f14::detail::F14BasicMap<Policy>::EnableHeterogeneousFind<K, long unsigned int> folly::f14::detail::F14BasicMap<Policy>::count(const K&) const [with K = int; Policy = folly::f14::detail::ValueContainerPolicy<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1>, void>]’ at folly/container/F14Map.h:789:20, inlined from ‘void runHeterogeneousInsertTest() [with M = folly::F14FastMap<folly::test::Tracked<1>, int, folly::test::TransparentTrackedHash<1>, folly::test::TransparentTrackedEqual<1> >]’ at folly/container/test/F14MapTest.cpp:1800:3: /opt/rh/gcc-toolset-13/root/usr/include/c++/13/array:213:24: warning: array subscript 0 is outside array bounds of ‘const folly::f14::detail::F14EmptyTagVector [1]’ [-Warray-bounds=] 213 | return _M_elems[__n]; | ~~~~~~~~^ ``` Reviewed By: ilvokhin Differential Revision: D67791477 fbshipit-source-id: 78a82789dec0c04eda176111a2e4db241decaabf
1 parent f13da9f commit 380c005

File tree

1 file changed

+14
-0
lines changed
  • third-party/folly/src/folly/container/detail

1 file changed

+14
-0
lines changed

third-party/folly/src/folly/container/detail/F14Table.h

+14
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,15 @@ using Defaulted =
458458
template <typename T>
459459
FOLLY_ALWAYS_INLINE static void prefetchAddr(T const* ptr) {
460460
#ifndef _WIN32
461+
FOLLY_PUSH_WARNING
462+
FOLLY_GNU_DISABLE_WARNING("-Warray-bounds")
463+
/// The argument ptr is permitted to be wild, since wild pointers are allowed
464+
/// for prefetching on every architecture. While this behavior is technically
465+
/// undefined (forbidden) in C and C++, we need this behavior in order to
466+
/// avoid extra cost in the callers. Recent versions of GCC warn when they
467+
/// detect uses of pointers which may be wild. So we suppress the warning.
461468
__builtin_prefetch(static_cast<void const*>(ptr));
469+
FOLLY_POP_WARNING
462470
#elif FOLLY_NEON
463471
__prefetch(static_cast<void const*>(ptr));
464472
#elif FOLLY_SSE >= 2
@@ -745,13 +753,19 @@ struct alignas(kRequiredVectorAlignment) F14Chunk {
745753
return tags_[index] != 0;
746754
}
747755

756+
/// Permitted to return a wild pointer, which is allowed for prefetching on
757+
/// every architecture. This behavior is technically undefined (forbidden) in
758+
/// C and C++, but we violate the rule in order to avoid extra cost in the
759+
/// prefetch paths. The wild pointer that may be returned is whatever follows
760+
/// any empty-instance global in the memory of any DSO.
748761
Item* itemAddr(std::size_t i) const {
749762
return static_cast<Item*>(
750763
const_cast<void*>(static_cast<void const*>(&rawItems_[i])));
751764
}
752765

753766
Item& item(std::size_t i) {
754767
FOLLY_SAFE_DCHECK(this->occupied(i), "");
768+
compiler_may_unsafely_assume(this != getSomeEmptyInstance());
755769
return *std::launder(itemAddr(i));
756770
}
757771

0 commit comments

Comments
 (0)