forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ban absl::FixedArray, and instead provide base::FixedArray.
This is just a type wrapper, but it modifies a constructor that otherwise would allow UB. Bug: none Change-Id: I368deca0af8b51afa0b206bc420576982dee7313 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4895257 Auto-Submit: Peter Kasting <pkasting@chromium.org> Reviewed-by: Danil Chapovalov <danilchap@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Peter Kasting <pkasting@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#1203043}
- Loading branch information
Showing
6 changed files
with
131 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
specific_include_rules = { | ||
# Provides the canonical access point for this type | ||
"fixed_array.h": [ | ||
"+third_party/abseil-cpp/absl/container/fixed_array.h", | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef BASE_TYPES_FIXED_ARRAY_H_ | ||
#define BASE_TYPES_FIXED_ARRAY_H_ | ||
|
||
#include <stddef.h> | ||
|
||
#include <memory> | ||
#include <type_traits> | ||
|
||
#include "third_party/abseil-cpp/absl/container/fixed_array.h" | ||
|
||
namespace base { | ||
|
||
// `FixedArray` provides `absl::FixedArray` in Chromium, but when `T` is | ||
// trivially-default-constructible, forces the no-default-value constructor to | ||
// initialize the elements to `T()`, instead of leaving them uninitialized. This | ||
// makes `base::FixedArray` behave like `std::vector` instead of `std::array` | ||
// and avoids the risk of UB. | ||
|
||
// Trivially-default-constructible case: no-value constructor should init | ||
template <typename T, | ||
size_t N = absl::kFixedArrayUseDefault, | ||
typename A = std::allocator<T>, | ||
typename = void> | ||
class FixedArray : public absl::FixedArray<T, N, A> { | ||
public: | ||
using absl::FixedArray<T, N, A>::FixedArray; | ||
explicit FixedArray(absl::FixedArray<T, N, A>::size_type n, | ||
const absl::FixedArray<T, N, A>::allocator_type& a = | ||
typename absl::FixedArray<T, N, A>::allocator_type()) | ||
: FixedArray(n, T(), a) {} | ||
}; | ||
|
||
// Non-trivially-default-constructible case: Pass through all constructors | ||
template <typename T, size_t N, typename A> | ||
struct FixedArray< | ||
T, | ||
N, | ||
A, | ||
std::enable_if_t<!std::is_trivially_default_constructible_v<T>>> | ||
: public absl::FixedArray<T, N, A> { | ||
using absl::FixedArray<T, N, A>::FixedArray; | ||
}; | ||
|
||
} // namespace base | ||
|
||
#endif // BASE_TYPES_FIXED_ARRAY_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "base/types/fixed_array.h" | ||
|
||
#include <stddef.h> | ||
|
||
#include <cstring> | ||
#include <memory> | ||
#include <type_traits> | ||
|
||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace base { | ||
namespace { | ||
|
||
TEST(FixedArrayTest, TriviallyDefaultConstructibleInitializes) { | ||
using T = int; | ||
static_assert(std::is_trivially_default_constructible_v<T>); | ||
using Array = FixedArray<T, 1>; | ||
|
||
// First try an array on the stack. | ||
Array stack_array(1); | ||
// This read and the one below are UB if `FixedArray` does not initialize the | ||
// elements, but hopefully even if the compiler chooses to zero memory anyway, | ||
// the test will fail under the memory sanitizer. | ||
EXPECT_EQ(0, stack_array[0]); | ||
|
||
// Now try an array on the heap, where we've purposefully written a non-zero | ||
// bitpattern in hopes of increasing the chance of catching incorrect | ||
// behavior. | ||
constexpr size_t kSize = sizeof(Array); | ||
alignas(Array) char storage[kSize]; | ||
std::memset(storage, 0xAA, kSize); | ||
Array* placement_new_array = new (storage) Array(1); | ||
EXPECT_EQ(0, (*placement_new_array)[0]); | ||
placement_new_array->~Array(); | ||
} | ||
|
||
} // namespace | ||
} // namespace base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters