Skip to content

Commit 6343aee

Browse files
committed
runtime: identify potential miscompiles
`operator new` up until C++17 was alignment unaware. We use C++ types decorated with `alignas` to enforce 16-byte alignment. This is fine on the current platforms that we support as they are all enforcing 16-byte alignment on allocations. However, this is not a guarantee that C++ makes. It only provides the guarantee that `operator new` will align the memory to `__STDCPP_DEFAULT_NEW_ALIGNMENT__`. On 32-bit platforms such as Windows i686, this value is actually 8. However, due to the class(es) being attributed as `alignas(16)`, the default constructor which is emitted by the compiler assumes the proper alignment will be provided for externally and will zero the memory using the following sequence: ~~~ xorps xmm0, xmm0 movaps xmm0, [eax] movaps xmm0, [eax+16] ~~~ This assumes that the returned pointer is suitably aligned for XMM operations - 16-bytes - as the attribution indicates as such. This misalignment would cause a bus error on Linux, and more confusingly triggers an invalid access (the equivalent of a segmentation fault) on Windows. Add a static assertion to identify this unintended misalignment on allocation. This check will be meaningless post C++17 as that will use a two-phase overload resolution for `operator new`, preferring the newly introduced `operator new(std::size_t, std::align_val_t)` which would suitably align the type and as such is guarded by the feature macro `__cpp_aligned_new`.
1 parent df913c9 commit 6343aee

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

include/swift/Runtime/AtomicWaitQueue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,10 @@ class AtomicWaitQueue {
424424
private:
425425
template <class... Args>
426426
static Impl *createNewQueue(Args &&...args) {
427+
#if !defined(__cpp_aligned_new)
428+
static_assert(std::alignment_of<Impl>::value <= __STDCPP_DEFAULT_NEW_ALIGNMENT__,
429+
"type is over-aligned for non-alignment aware operator new");
430+
#endif
427431
auto queue = new Impl(std::forward<Args>(args)...);
428432
queue->WaitQueueLock.lock();
429433
return queue;

0 commit comments

Comments
 (0)