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