public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++/77686 use may_alias for std::function storage
@ 2016-09-28 11:17 Jonathan Wakely
  2016-09-28 11:17 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2016-09-28 11:17 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

std::function::swap does swap(_M_functor, x._M_functor) which
exchanges the underlying bytes of the two _Any_data PODs using that
type's implicit assignment operator. However, unlike using placement
new to construct an object in the storage, simply memcpying the bytes
doesn't change the effective type of the storage, so alias analysis
decides it can't point to whatever we've tried to store in there.

This attribute tells the middle-end to assume anything those bytes
could contain any type of object, which is exactly what we want.

	PR libstdc++/77686
	* include/std/functional (_Any_data): Add may_alias attribute.

Tested powerpc64le-linux, committing to trunk and gcc-6-branch.

std::any doesn't have the same problem, because I defined an _Op_xfer
operation that uses placement new to copy the object into the
destination, so the dynamic type is changed correctly.  I haven't
checked whether optional and variant might have similar problems in
any implicit copy/move operations working on POD storage.



[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 812 bytes --]

commit f8578f058f049c36ddfae1bf654f3dc93fd8b7ef
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Sep 28 11:41:08 2016 +0100

    libstdc++/77686 use may_alias for std::function storage
    
    	PR libstdc++/77686
    	* include/std/functional (_Any_data): Add may_alias attribute.

diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 8b2389c..74e65c7 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -1401,7 +1401,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
     void (_Undefined_class::*_M_member_pointer)();
   };
 
-  union _Any_data
+  union [[gnu::may_alias]] _Any_data
   {
     void*       _M_access()       { return &_M_pod_data[0]; }
     const void* _M_access() const { return &_M_pod_data[0]; }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libstdc++/77686 use may_alias for std::function storage
  2016-09-28 11:17 [PATCH] libstdc++/77686 use may_alias for std::function storage Jonathan Wakely
@ 2016-09-28 11:17 ` Richard Biener
  2016-09-28 11:28   ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2016-09-28 11:17 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, GCC Patches

On Wed, Sep 28, 2016 at 12:57 PM, Jonathan Wakely <jwakely@redhat.com> wrote:
> std::function::swap does swap(_M_functor, x._M_functor) which
> exchanges the underlying bytes of the two _Any_data PODs using that
> type's implicit assignment operator. However, unlike using placement
> new to construct an object in the storage, simply memcpying the bytes
> doesn't change the effective type of the storage, so alias analysis
> decides it can't point to whatever we've tried to store in there.

To clarify -- the implicit assingment operator for PODs (including unions)
simply expands to an aggregate assignment which is subject to TBAA
rules and thus in this case instantiates an effective type of _Any_data.
Using memcpy would have worked as memcpy _does_ transfer
the effective type of the storage.  It wasn't points-to deciding things
here but TBAA given automatic storage X with effective type T
read via an lvalue of type _Any_data.

> This attribute tells the middle-end to assume anything those bytes
> could contain any type of object, which is exactly what we want.

It tells the middle-end that accessing storage via a _pointer_ to such
marked type may access storage with a dynamic type that is not
compatible with the type.

Details ;)

Btw, I think the patch is correct.

Richard.

>         PR libstdc++/77686
>         * include/std/functional (_Any_data): Add may_alias attribute.
>
> Tested powerpc64le-linux, committing to trunk and gcc-6-branch.
>
> std::any doesn't have the same problem, because I defined an _Op_xfer
> operation that uses placement new to copy the object into the
> destination, so the dynamic type is changed correctly.  I haven't
> checked whether optional and variant might have similar problems in
> any implicit copy/move operations working on POD storage.
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libstdc++/77686 use may_alias for std::function storage
  2016-09-28 11:17 ` Richard Biener
@ 2016-09-28 11:28   ` Jonathan Wakely
  0 siblings, 0 replies; 3+ messages in thread
From: Jonathan Wakely @ 2016-09-28 11:28 UTC (permalink / raw)
  To: Richard Biener; +Cc: libstdc++, GCC Patches

On 28/09/16 13:14 +0200, Richard Biener wrote:
>On Wed, Sep 28, 2016 at 12:57 PM, Jonathan Wakely <jwakely@redhat.com> wrote:
>> std::function::swap does swap(_M_functor, x._M_functor) which
>> exchanges the underlying bytes of the two _Any_data PODs using that
>> type's implicit assignment operator. However, unlike using placement
>> new to construct an object in the storage, simply memcpying the bytes
>> doesn't change the effective type of the storage, so alias analysis
>> decides it can't point to whatever we've tried to store in there.
>
>To clarify -- the implicit assingment operator for PODs (including unions)
>simply expands to an aggregate assignment which is subject to TBAA
>rules and thus in this case instantiates an effective type of _Any_data.
>Using memcpy would have worked as memcpy _does_ transfer
>the effective type of the storage.  It wasn't points-to deciding things
>here but TBAA given automatic storage X with effective type T
>read via an lvalue of type _Any_data.
>
>> This attribute tells the middle-end to assume anything those bytes
>> could contain any type of object, which is exactly what we want.
>
>It tells the middle-end that accessing storage via a _pointer_ to such
>marked type may access storage with a dynamic type that is not
>compatible with the type.
>
>Details ;)

But important ones, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-09-28 11:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-28 11:17 [PATCH] libstdc++/77686 use may_alias for std::function storage Jonathan Wakely
2016-09-28 11:17 ` Richard Biener
2016-09-28 11:28   ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).