https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349

Christopher Nerz <Christopher.Nerz at de dot bosch.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Christopher.Nerz at de dot 
bosch.c
                   |                            |om

--- Comment #45 from Christopher Nerz <Christopher.Nerz at de dot bosch.com> ---
This is a critical bug which renders gcc unusable for safety relevant systems
using expected/variant or simple ipc.

You can get the same buggy behavior with far simpler code:
https://godbolt.org/z/1WTnnYceM


#include <cstdint>
#include <memory>

bool check()
{
    // Just to prove that it is not a problem with alignment etc.
    static_assert(alignof(double) == alignof(std::uint64_t));
    static_assert(sizeof(double) == sizeof(std::uint64_t));

    alignas(8) std::byte buffer[8]; // some buffer
    new (buffer) double{1}; // some completely trivial data
    // reuse memory -> double ends lifetime, uint64 starts lifetime
    std::uint64_t * res = new (buffer) std::uint64_t;
    // *res is allowed to be used as it is the correct pointer returned by new
    // *res == 0x3ff0000000000000 // and gives correct value
    // The very definition of std::launder says that it is suppose to be used
as:
    return (*res == *std::launder(reinterpret_cast<std::uint64_t*>(buffer)));
}

int main(int argc, char **argv) {
    return check(); // gives false with activatred O2 (true with O0)
}


We get the same behavior when initialisating the memory at our version of
"std::uint64_t * res = new (buffer) std::uint64_t;", but were unable to give a
minimal example for that behavior.

Reply via email to