Consider use of __builtin_launder
The UPC++ runtime sometimes needs to "launder" pointers, creating a valid T*
using bits that didn't previously meet the C++ definition of a valid T*
. This notably arises in detail::raw_storage
which is used to create storage for objects while maintaining "manual" control over their construction and destruction.
We do our laundry using detail::launder()
which uses std::launder
when available. Unfortunately the latter is a C++17 feature, which means it's only available in some of the newest compiler versions, and even then only when the header (read: the application code) is built using -std=c++17
or greater. Here's the current overview of where std::launder
available:
- g++ 6.4.0, clang++ 4.0.0, intel 17.2 (our floors) DON’T support std::launder at all
- GNU g++ 7.1.0…10.3.0 DO support, but only for language levels >= 17
- same with GNU g++ 11.1.0+, although this compiler defaults to c++17
- LLVM clang 8.0.0+ DO support, but only for language levels >= 17
- Intel 18.0+ DO support, but only for language levels >= 17
- PGI does not support std::launder at all
In the absence of std::launder
, we use an inline volatile asm
with GNU-style dependency annotations that tell the compiler we "killed" the memory in question, so the analysis has to conservatively assume we may have constructed an object in that memory. This mostly works, but is overkill and probably hurts the analysis more than necessary (especially for "less robust" compilers whose analysis doesn't fully understand the GNU asm annotations and might just conservatively treat every asm as potentially killing all of memory).
@Colin MacLean has suggested (and I agree) that we could instead use __builtin_launder
(when available) as a more surgical approach when std::launder
is missing for whatever reason. It appears __builtin_launder
was added in GCC 7.1.0 (2017) / clang 8.0.0 (2019) / intel 2018.1 - so pretty much the same version space, but unlike std::launder
it is available in all language modes.
FWIW __has_builtin(__builtin_launder)
does NOT appear to be reliably precise for detecting this feature, as (based on my testing) GCC doesn't answer "yes" for that until v10.1 -- so we should probably use a configure check for __builtin_launder
instead.
Comments (2)
-
-
- changed status to resolved
- Log in to comment
Resolved by PR 358.