Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/google/ruy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Jacob <benoitjacob@google.com>2022-01-21 19:17:21 +0300
committerCopybara-Service <copybara-worker@google.com>2022-01-21 19:17:48 +0300
commit2d950b3bfa7ebfbe7a97ecb44b1cc4da5ac1d6f0 (patch)
tree85a3920793e0f6ef80c9b1efeb14dac14adc75b5
parentabaaa6a6a5515cfe958cf7b32ae1f2e5ca1b962f (diff)
Accomodate Clang's CFI sanitizer
It was complaining that the `TrMulTask* tasks` pointer was temporarily pointing to garbage as we first set it to point to the allocated buffer, then perform the actual TrMulTask object constructions using placement-new. Rewritten so that the pointer is kept a `char*` pointer during this allocation and placement-new business, and only assigned to a TrMulTasks* pointer at the end. Note: this is *not* a strict-aliasing issue. The CFI diagnostic here is unaffected by `-f[no-]strict-aliasing` and the reason why this isn't a strict-aliasing violation is that the C++ spec makes an exception for `char` and a couple of other byte types, allowing to make byte buffers alias objects of other types. So CFI is going beyond the C++ spec here --- this isn't an undefined-behavior report. This is apparently trying to enforce that if pointers are set at all then they must be set to point to a valid object of their element type. At least for types that have a vtable. PiperOrigin-RevId: 423326986
-rw-r--r--ruy/trmul.cc18
1 files changed, 10 insertions, 8 deletions
diff --git a/ruy/trmul.cc b/ruy/trmul.cc
index 602660b..dbf5feb 100644
--- a/ruy/trmul.cc
+++ b/ruy/trmul.cc
@@ -377,20 +377,22 @@ void TrMul(Ctx* ctx, TrMulParams* params) {
// reservation granule.
std::atomic<int>* atomic_block_id;
main_allocator->Allocate(1, &atomic_block_id);
-
- // Create task objects.
- TrMulTask* tasks;
- main_allocator->Allocate(thread_count, &tasks);
-
atomic_block_id->store(thread_count);
+ // Create task objects. We allocate a single buffer and then use placement-new
+ // to construct N TrMulTask objects within it. To avoid having the Clang CFI
+ // sanitizer complain about a TrMulTask* pointer temporarily pointing to
+ // garbage, we keep the pointer a plain char* until finished constructing.
+ char* tasks_buf =
+ main_allocator->Allocate<char>(thread_count * sizeof(TrMulTask));
for (int i = 0; i < thread_count; i++) {
auto* allocator = ctx->GetThreadSpecificAllocator(i);
auto* tuning_resolver = ctx->GetThreadSpecificTuningResolver(i);
- new (tasks + i) TrMulTask(params, block_map, atomic_block_id, i,
- need_atomics, packing_status, tuning_resolver,
- allocator, ctx->mutable_cpuinfo());
+ new (tasks_buf + i * sizeof(TrMulTask)) TrMulTask(
+ params, block_map, atomic_block_id, i, need_atomics, packing_status,
+ tuning_resolver, allocator, ctx->mutable_cpuinfo());
}
+ TrMulTask* tasks = reinterpret_cast<TrMulTask*>(tasks_buf);
// Do the computation.
ctx->mutable_thread_pool()->Execute(thread_count, tasks);