Skip to content

Commit 6c41afe

Browse files
[SYCL] Trick GCC to avoid strict pointer aliasing warnings (#1203)
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 <[email protected]>
1 parent 8d77a38 commit 6c41afe

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

sycl/include/CL/sycl/property_list.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@ template <class T> class PropertyHolder {
8484

8585
~PropertyHolder() {
8686
if (m_Initialized) {
87-
(*(T *)m_Mem).~T();
87+
T *MemPtr = reinterpret_cast<T *>(m_Mem);
88+
MemPtr->~T();
8889
}
8990
}
9091

9192
PropertyHolder &operator=(const PropertyHolder &Other) {
9293
if (this != &Other) {
9394
if (m_Initialized) {
94-
(*(T *)m_Mem).~T();
95+
T *MemPtr = reinterpret_cast<T *>(m_Mem);
96+
MemPtr->~T();
9597
m_Initialized = false;
9698
}
9799

@@ -110,7 +112,8 @@ template <class T> class PropertyHolder {
110112

111113
const T &getProp() const {
112114
assert(true == m_Initialized && "Property was not set!");
113-
return *(const T *)m_Mem;
115+
const T *MemPtr = reinterpret_cast<const T *>(m_Mem);
116+
return *MemPtr;
114117
}
115118
bool isInitialized() const { return m_Initialized; }
116119

0 commit comments

Comments
 (0)