public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/112591] New: variant allows for creating multiple empty objects at same address
@ 2023-11-17 16:02 barry.revzin at gmail dot com
  2023-11-17 16:53 ` [Bug libstdc++/112591] " barry.revzin at gmail dot com
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: barry.revzin at gmail dot com @ 2023-11-17 16:02 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 112591
           Summary: variant allows for creating multiple empty objects at
                    same address
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

Consider:

#include <variant>
#include <iostream>

struct Empty { ~Empty() {} };
struct Sub : Empty { std::variant<Empty> e; };

int main() {
    Sub v;

    Empty* base = &v;
    Empty* obj = &std::get<Empty>(v.e);

    std::cout
        << "base=" << (void*)base
        << " obj=" << (void*)obj
        << " matches=" << (base == obj)
        << '\n';
}

In C++17 mode on trunk, base and obj have the same address.
In C++20 mode up through 11.4, they have the same address. Since 12.1, they do
not.

If Empty were trivially destructible, they never have the same address.

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

* [Bug libstdc++/112591] variant allows for creating multiple empty objects at same address
  2023-11-17 16:02 [Bug libstdc++/112591] New: variant allows for creating multiple empty objects at same address barry.revzin at gmail dot com
@ 2023-11-17 16:53 ` barry.revzin at gmail dot com
  2023-11-17 17:21 ` redi at gcc dot gnu.org
  2023-11-19 21:48 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: barry.revzin at gmail dot com @ 2023-11-17 16:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Barry Revzin <barry.revzin at gmail dot com> ---
Basically, in C++17, Sub looks like this:

struct Sub17 : Empty {
    aligned_membuf<Empty> storage;
    unsigned char index;
};

But in C++20 it turns into:

struct Sub20 : Empty {
    union { Empty storage; };
    unsigned char index;
};

sizeof(Sub17) == 2 because of the empty base optimization, but sizeof(Sub20) ==
3 because now the language understands that storage is an Empty and thus needs
a distinct address from the Empty base class.

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

* [Bug libstdc++/112591] variant allows for creating multiple empty objects at same address
  2023-11-17 16:02 [Bug libstdc++/112591] New: variant allows for creating multiple empty objects at same address barry.revzin at gmail dot com
  2023-11-17 16:53 ` [Bug libstdc++/112591] " barry.revzin at gmail dot com
@ 2023-11-17 17:21 ` redi at gcc dot gnu.org
  2023-11-19 21:48 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-17 17:21 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Ughhhhhhhh. The C++20 behaviour is correct, but fixing it for C++17 is an ABI
change. I think we need to do it though.

It should work to change the C++17 variant to use a union of
__aligned_membuf<Empty> and Empty, and then just ignore the latter (or maybe we
can use the C++20 impl for C++17 too?)

This is a more general problem with __aligned_membuf, it's just that
std::variant is probably the only place you can trigger it, because you can't
have a data member of types such as _Rb_tree_node<Empty>. We could change
aligned_membuf to use a union internally, so that anything using aligned_membuf
avoids having the same problem.

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

* [Bug libstdc++/112591] variant allows for creating multiple empty objects at same address
  2023-11-17 16:02 [Bug libstdc++/112591] New: variant allows for creating multiple empty objects at same address barry.revzin at gmail dot com
  2023-11-17 16:53 ` [Bug libstdc++/112591] " barry.revzin at gmail dot com
  2023-11-17 17:21 ` redi at gcc dot gnu.org
@ 2023-11-19 21:48 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-19 21:48 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2023-11-19
     Ever confirmed|0                           |1

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed.

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

end of thread, other threads:[~2023-11-19 21:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-17 16:02 [Bug libstdc++/112591] New: variant allows for creating multiple empty objects at same address barry.revzin at gmail dot com
2023-11-17 16:53 ` [Bug libstdc++/112591] " barry.revzin at gmail dot com
2023-11-17 17:21 ` redi at gcc dot gnu.org
2023-11-19 21:48 ` pinskia at gcc dot gnu.org

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).