public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "pinskia at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/115050] Segfault when compiled with -O0 Date: Tue, 28 May 2024 21:43:29 +0000 [thread overview] Message-ID: <bug-115050-4-goxzeZzlfz@http.gcc.gnu.org/bugzilla/> (raw) In-Reply-To: <bug-115050-4@http.gcc.gnu.org/bugzilla/> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115050 Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- There is a copy of Tester involved before F's constructor fully happens so we call ~FBase (on the unwind) which then calls the bad (vtable) deconstructor. Why it happens at -O0 only is just by accident. At -O1 we do some de-virtualization which allows the (right) deconstructor to be called. Note GCC's VTable::~VTable sets the vtable to be VTable's vtable which exposes the bug. This only happens at -O0 because at -O1 and above it is considered a dead store. This is definitely undefined code without the following change because you might get ~VTable being called twice. Note if you change VTable to: ``` class VTable { public: virtual void func(int x) = 0; // #1 this line affects behavior virtual ~VTable() {__builtin_printf("~vtable\n");} }; ``` You will see there is 2 calls to ~VTable which is incorrect. Changing FBase/F to this: ``` struct FBase { static constexpr int S = sizeof(void*) + sizeof(VTable); bool constructed = false; std::byte _data[S]; ~FBase() { if (!constructed) return; static_cast<VTable*>(static_cast<void*>(&_data[0]))->~VTable(); } // #2 this line affects behavior }; struct F : FBase { template <typename T> F(T&& t) { static_assert(sizeof(Handler<std::decay_t<T>>) <= S); ::new (&_data[0]) Handler<std::decay_t<T>>(std::forward<T>(t)); constructed = true; } ~F() = default; }; ``` Fixes the issue and only one call to ~VTable happens.
prev parent reply other threads:[~2024-05-28 21:43 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-05-12 11:40 [Bug c++/115050] New: " lobel.krivic at proton dot me 2024-05-12 11:44 ` [Bug c++/115050] " pinskia at gcc dot gnu.org 2024-05-12 15:50 ` sjames at gcc dot gnu.org 2024-05-28 21:43 ` pinskia at gcc dot gnu.org [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-115050-4-goxzeZzlfz@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).