diff --git a/src/bsoncxx/include/bsoncxx/v1/exception.hpp b/src/bsoncxx/include/bsoncxx/v1/exception.hpp index 70ba0df54b..a099506ce7 100644 --- a/src/bsoncxx/include/bsoncxx/v1/exception.hpp +++ b/src/bsoncxx/include/bsoncxx/v1/exception.hpp @@ -97,14 +97,10 @@ BSONCXX_PRIVATE_WARNINGS_DISABLE(MSVC(4275)); /// class exception : public std::system_error { public: - ~exception() override; - - exception(exception&&) noexcept = default; - exception& operator=(exception&&) noexcept = default; - exception(exception const&) = default; - exception& operator=(exception const&) = default; - using std::system_error::system_error; + + private: + BSONCXX_ABI_NO_EXPORT virtual void key_function() const; }; BSONCXX_PRIVATE_WARNINGS_POP(); diff --git a/src/bsoncxx/lib/bsoncxx/v1/exception.cpp b/src/bsoncxx/lib/bsoncxx/v1/exception.cpp index 2d655243bc..4f656bcffb 100644 --- a/src/bsoncxx/lib/bsoncxx/v1/exception.cpp +++ b/src/bsoncxx/lib/bsoncxx/v1/exception.cpp @@ -85,7 +85,14 @@ std::error_category const& type_error_category() { namespace bsoncxx { namespace v1 { -exception::~exception() = default; +// Prevent vague linkage of the vtable and type_info object (-Wweak-vtables). +// - https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable +// > The key function is the first non-pure virtual function that is not inline at the point of class definition. +// - https://lld.llvm.org/missingkeyfunction: +// > It’s always advisable to ensure there is at least one eligible function that can serve as the key function. +// - https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html +// > For polymorphic classes (classes with virtual functions), the ‘type_info’ object is written out along with the vtable. +void exception::key_function() const {} } // namespace v1 } // namespace bsoncxx diff --git a/src/mongocxx/include/mongocxx/v1/exception.hpp b/src/mongocxx/include/mongocxx/v1/exception.hpp index 77c63dc08b..5a2e8845f7 100644 --- a/src/mongocxx/include/mongocxx/v1/exception.hpp +++ b/src/mongocxx/include/mongocxx/v1/exception.hpp @@ -100,14 +100,10 @@ BSONCXX_PRIVATE_WARNINGS_DISABLE(MSVC(4275)); /// class exception : public std::system_error { public: - ~exception() override; - - exception(exception&&) noexcept = default; - exception& operator=(exception&&) noexcept = default; - exception(exception const&) = default; - exception& operator=(exception const&) = default; - using std::system_error::system_error; + + private: + MONGOCXX_ABI_NO_EXPORT virtual void key_function() const; }; BSONCXX_PRIVATE_WARNINGS_POP(); diff --git a/src/mongocxx/lib/mongocxx/v1/exception.cpp b/src/mongocxx/lib/mongocxx/v1/exception.cpp index ab29a888c3..5bc0f8e1a3 100644 --- a/src/mongocxx/lib/mongocxx/v1/exception.cpp +++ b/src/mongocxx/lib/mongocxx/v1/exception.cpp @@ -83,7 +83,14 @@ std::error_category const& type_error_category() { return instance.value(); } -exception::~exception() = default; +// Prevent vague linkage of the vtable and type_info object (-Wweak-vtables). +// - https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable +// > The key function is the first non-pure virtual function that is not inline at the point of class definition. +// - https://lld.llvm.org/missingkeyfunction: +// > It’s always advisable to ensure there is at least one eligible function that can serve as the key function. +// - https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html +// > For polymorphic classes (classes with virtual functions), the ‘type_info’ object is written out along with the vtable. +void exception::key_function() const {} } // namespace v1 } // namespace mongocxx