From 9e69922619440586de5b171074c632ab259aa4f5 Mon Sep 17 00:00:00 2001 From: Alexey Sachkov Date: Wed, 26 Feb 2020 19:11:26 +0300 Subject: [PATCH] [SYCL] Trick to avoid strict pointer aliasing warnings The problem is that gcc < 7.2 emit the following warning: ``` warning: dereferencing type-punned pointer will break stric t-aliasing rules [-Wstrict-aliasing] (*(T *)m_Mem).~T(); ^ ``` Interesting, that this only happens with `-O2` optimization level Replaced C-style casts with C++ `reinterpret_cast` and this is actually quite a hack, because according to the docs [1]: > the resulting pointer may only be dereferenced safely if allowed by > the type aliasing rules Type aliasing rules allow to represent any object as `char *`, but not the way around, i.e. array of characters cannot be reinterpreted as an object. `std::memcpy` also doesn't work here, because there is no requirement that `T` is trivially copyable. Another way to trick a compiler is to save pointer returned from placement new: it already has type `T *`, so, we can store it within the class and avoid casts. Hovewer, this is also a tricky thing, because since `m_Mem` and this new pointer point to different types, compiler could assume that they don't alias (when they actually point to the same memory location) and perform some undesired transformations. [1]: https://en.cppreference.com/w/cpp/language/reinterpret_cast Signed-off-by: Alexey Sachkov --- sycl/include/CL/sycl/property_list.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sycl/include/CL/sycl/property_list.hpp b/sycl/include/CL/sycl/property_list.hpp index 439b2b1acc931..fbc3ef7bf5402 100644 --- a/sycl/include/CL/sycl/property_list.hpp +++ b/sycl/include/CL/sycl/property_list.hpp @@ -84,14 +84,16 @@ template class PropertyHolder { ~PropertyHolder() { if (m_Initialized) { - (*(T *)m_Mem).~T(); + T *MemPtr = reinterpret_cast(m_Mem); + MemPtr->~T(); } } PropertyHolder &operator=(const PropertyHolder &Other) { if (this != &Other) { if (m_Initialized) { - (*(T *)m_Mem).~T(); + T *MemPtr = reinterpret_cast(m_Mem); + MemPtr->~T(); m_Initialized = false; } @@ -110,7 +112,8 @@ template class PropertyHolder { const T &getProp() const { assert(true == m_Initialized && "Property was not set!"); - return *(const T *)m_Mem; + const T *MemPtr = reinterpret_cast(m_Mem); + return *MemPtr; } bool isInitialized() const { return m_Initialized; }