From https://gcc.gnu.org/ml/gcc-help/2015-09/msg00015.html The following class when compiled with g++ 4.9.2 emits the vtable for class Foo: class Foo { virtual void dosomething() { } virtual ~Foo() noexcept __attribute__((used)) { } }; The following class when compiled does not emit the vtable: class Foo { virtual void dosomething() { } virtual ~Foo() noexcept __attribute__((used)) = default; };
The bug is that we aren't emitting ~Foo even though it's marked used; the vtable is just a side effect.
We don't emit any constructors or destructors that are marked used. This is a problem for libstdc++ now. struct S { S(); ~S(); S(const S&); }; [[gnu::used]] inline S::S() { } [[gnu::used]] inline S::~S() { } [[gnu::used]] inline S::S(const S&) { } This generates no code with GCC. Clang emits all three functions.
Created attachment 49509 [details] gcc11-pr67453.patch Untested fix.
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:710508c7b1a2c8e1d75d4c4f1ac79473dbf2b2bb commit r11-4749-g710508c7b1a2c8e1d75d4c4f1ac79473dbf2b2bb Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Nov 5 16:19:15 2020 +0000 libstdc++: Fix multiple definitions of std::exception_ptr functions [PR 97729] This fixes some multiple definition errors caused by the changes for PR libstdc++/90295. The previous solution for inlining the members of std::exception_ptr but still exporting them from the library was to suppress the 'inline' keyword on those functions when compiling libsupc++/eh_ptr.cc, so they get defined in that file. That produces ODR violations though, because there are now both inline and non-inline definitions in the library, due to the use of std::exception_ptr in other files sucg as src/c++11/future.cc. The new solution is to define all the relevant members as 'inline' unconditionally, but use __attribute__((used)) to cause definitions to be emitted in libsupc++/eh_ptr.cc as before. This doesn't quite work however, because PR c++/67453 means the attribute is ignored on constructors and destructors. As a workaround, the old solution (conditionally inline) is still used for those members, but they are given the always_inline attribute so that they aren't emitted in src/c++11/future.o as inline definitions. libstdc++-v3/ChangeLog: PR libstdc++/97729 * include/std/future (__basic_future::_M_get_result): Use nullptr for null pointer constant. * libsupc++/eh_ptr.cc (operator==, operator!=): Remove definitions. * libsupc++/exception_ptr.h (_GLIBCXX_EH_PTR_USED): Define macro to conditionally add __attribute__((__used__)). (operator==, operator!=, exception_ptr::exception_ptr()) (exception_ptr::exception_ptr(const exception_ptr&)) (exception_ptr::~exception_ptr()) (exception_ptr::operator=(const exception_ptr&)) (exception_ptr::swap(exception_ptr&)): Always define as inline. Add macro to be conditionally "used".
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:6c282c14d1be0bba2bf5d49acd074b349f28ad17 commit r11-4798-g6c282c14d1be0bba2bf5d49acd074b349f28ad17 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Nov 6 20:33:39 2020 +0100 c++: Propagate attributes to clones in duplicate_decls [PR67453] On the following testcase where the cdtor attributes aren't on the in-class declaration but on an out-of-class definition, the cdtors have their clones created from the in-class declaration, and later on duplicate_decls updates attributes on the abstract cdtors, but nothing propagates them to the clones. 2020-11-06 Jakub Jelinek <jakub@redhat.com> PR c++/67453 * decl.c (duplicate_decls): Propagate DECL_ATTRIBUTES and DECL_PRESERVE_P from olddecl to its clones if any. * g++.dg/ext/attr-used-2.C: New test.
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:0af3930a497e022597a08fa1bcef5e453bfa636f commit r11-4839-g0af3930a497e022597a08fa1bcef5e453bfa636f Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Nov 9 10:16:07 2020 +0000 libstdc++: Use 'inline' consistently in std::exception_ptr [PR 97729] With PR c++/67453 fixed we can rely on the 'used' attribute to emit inline constructors and destructors in libsupc++/eh_ptr.cc. This means we don't need to suppress the 'inline' keyword on them in that file, and don't need to force 'always_inline' on them in other files. libstdc++-v3/ChangeLog: PR libstdc++/97729 * libsupc++/exception_ptr.h (exception_ptr::exception_ptr()) (exception_ptr::exception_ptr(const exception_ptr&)) (exception_ptr::~exception_ptr()): Remove 'always_inline' attributes. Use 'inline' unconditionally.
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:921661beb90edd14a6102e87f0ff71b5a21a70ee commit r10-9010-g921661beb90edd14a6102e87f0ff71b5a21a70ee Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Nov 6 20:33:39 2020 +0100 c++: Propagate attributes to clones in duplicate_decls [PR67453] On the following testcase where the cdtor attributes aren't on the in-class declaration but on an out-of-class definition, the cdtors have their clones created from the in-class declaration, and later on duplicate_decls updates attributes on the abstract cdtors, but nothing propagates them to the clones. 2020-11-06 Jakub Jelinek <jakub@redhat.com> PR c++/67453 * decl.c (duplicate_decls): Propagate DECL_ATTRIBUTES and DECL_PRESERVE_P from olddecl to its clones if any. * g++.dg/ext/attr-used-2.C: New test. (cherry picked from commit 6c282c14d1be0bba2bf5d49acd074b349f28ad17)