Skip to content

runtime: identify potential miscompiles #42130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2022

Conversation

compnerd
Copy link
Member

@compnerd compnerd commented Apr 1, 2022

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.

Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate.

Resolves SR-NNNN.

`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`.
@compnerd
Copy link
Member Author

compnerd commented Apr 1, 2022

CC: @mikeash @rjmccall

@compnerd
Copy link
Member Author

compnerd commented Apr 1, 2022

@swift-ci please test

@compnerd compnerd merged commit 541f772 into swiftlang:main Apr 2, 2022
@compnerd compnerd deleted the underaligned branch April 2, 2022 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants