std::optional defaut constructor

Marc Glisse marc.glisse@inria.fr
Thu Jun 4 11:44:31 GMT 2020


On Thu, 4 Jun 2020, Ville Voutilainen wrote:

> On Thu, 4 Jun 2020 at 11:53, Marc Glisse <marc.glisse@inria.fr> wrote:
>>
>> On Thu, 4 Jun 2020, Ville Voutilainen wrote:
>>
>>> On Thu, 4 Jun 2020 at 11:00, Marc Glisse <marc.glisse@inria.fr> wrote:
>>>> Maybe create a buffer, fill it with some non-zero values (-1?), then call
>>>> placement new, and read some value in the middle of the buffer, possibly
>>>> with some protection against optimizations? Ah, no, actual constructors
>>>> are fine, it is only the inlined initialization that happens with the
>>>> defaulted constructor that zeroes things.
>>>
>>> The zero-init is part of value-initialization of a class type with a
>>> defaulted default constructor, so value-initialization with placement
>>> new should indeed show us whether the target buffer is zeroed.
>>
>> Ah, yes, I had forgotten the empty () at the end of the operator new line
>> when testing. Now the patch makes this runtime test go from abort to
>> success at -O0 (with optimizations, the memset is removed as dead code). I
>> am still not sure we want this kind of test though. And I added launder
>> more to quiet a warning than with confidence that it does the right thing.
>>
>> #include <optional>
>> struct A {
>>    int a[1024];
>> };
>> typedef std::optional<A> O;
>> int main(){
>>    unsigned char t[sizeof(O)];
>>    __builtin_memset(t, -1, sizeof(t));
>>    new(t)O();
>>    if(std::launder(t)[512] != (unsigned char)(-1)) __builtin_abort();
>> }
>
> Yeah, I think the patch is OK with or without the test. As a side
> note, you don't need the launder
> if the check uses the pointer value returned by placement-new.

Yes, -fno-lifetime-dse is a better way to quiet the warning if
optimizations are enabled and documents why this test is unsafe. Here is
a version closer to what could go in the testsuite, although I'd still
rather not add it at this point. We'll see what Jonathan thinks.
(I didn't test this exact version)

// { dg-options "-std=gnu++17 -fno-lifetime-dse" }
// { dg-do run { target c++17 } }

#include <optional>
#include <testsuite_hooks.h>

struct A
{
   int a[1024];
};
typedef std::optional<A> O;

void
test01()
{
   unsigned char t[sizeof(O)];
   __builtin_memset(t, -1, sizeof(t));
   new (t) O();
   VERIFY( t[512] == (unsigned char)(-1) );
}

int
main()
{
   test01();
}


-- 
Marc Glisse


More information about the Libstdc++ mailing list