From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 204FD3858C2B for ; Thu, 5 Nov 2020 18:03:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 204FD3858C2B Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-270--JtZYmKFO5OuPy95lvR-Jw-1; Thu, 05 Nov 2020 13:03:14 -0500 X-MC-Unique: -JtZYmKFO5OuPy95lvR-Jw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3E8F8192CC49; Thu, 5 Nov 2020 18:03:13 +0000 (UTC) Received: from localhost (unknown [10.33.36.7]) by smtp.corp.redhat.com (Postfix) with ESMTP id D117C5C1CF; Thu, 5 Nov 2020 18:03:12 +0000 (UTC) Date: Thu, 5 Nov 2020 18:03:11 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [committed 1/2] libstdc++: Fix multiple definitions of std::exception_ptr functions [PR 97729] Message-ID: <20201105180311.GH503596@redhat.com> References: <20201105180152.GA3511218@redhat.com> MIME-Version: 1.0 In-Reply-To: <20201105180152.GA3511218@redhat.com> X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="MSd2ShuMixI0uVaZ" Content-Disposition: inline X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Nov 2020 18:03:18 -0000 --MSd2ShuMixI0uVaZ Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline 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. Tested powerpc64le-linux. Committed to trunk. --MSd2ShuMixI0uVaZ Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 710508c7b1a2c8e1d75d4c4f1ac79473dbf2b2bb Author: Jonathan Wakely Date: Thu Nov 5 16:19:15 2020 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". diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 3c2aaa1fab19..5d948018c75c 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -709,7 +709,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _State_base::_S_check(_M_state); _Result_base& __res = _M_state->wait(); - if (!(__res._M_error == 0)) + if (!(__res._M_error == nullptr)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index c41bdca234c7..7e6863550ce4 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -25,7 +25,12 @@ #include #include "eh_atomics.h" +#if ! _GLIBCXX_INLINE_VERSION +// This macro causes exception_ptr to declare an older API (with corresponding +// definitions in this file) and to mark some inline functions as "used" so +// that definitions will be emitted in this translation unit. #define _GLIBCXX_EH_PTR_COMPAT +#endif #include #include @@ -61,6 +66,8 @@ static_assert( adjptr<__cxa_exception>() #endif } +// Define non-inline functions. + std::__exception_ptr::exception_ptr::exception_ptr(void* obj) noexcept : _M_exception_object(obj) { _M_addref(); } @@ -130,19 +137,6 @@ std::__exception_ptr::exception_ptr::__cxa_exception_type() const noexcept return eh->exceptionType; } -// Retained for compatibility with CXXABI_1.3.12. -bool -std::__exception_ptr::operator==(const exception_ptr& lhs, - const exception_ptr& rhs) noexcept -{ return lhs._M_exception_object == rhs._M_exception_object; } - -// Retained for compatibility with CXXABI_1.3.12. -bool -std::__exception_ptr::operator!=(const exception_ptr& lhs, - const exception_ptr& rhs) noexcept -{ return !(lhs == rhs); } - - std::exception_ptr std::current_exception() noexcept { diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index 4497d0e8581b..001343ac0498 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -39,6 +39,12 @@ #include #include +#ifdef _GLIBCXX_EH_PTR_COMPAT +# define _GLIBCXX_EH_PTR_USED __attribute__((__used__)) +#else +# define _GLIBCXX_EH_PTR_USED +#endif + extern "C++" { namespace std @@ -146,20 +152,17 @@ namespace std { return _M_exception_object; } #endif -#ifdef _GLIBCXX_EH_PTR_COMPAT - friend bool - operator==(const exception_ptr&, const exception_ptr&) - _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); -#elif __cpp_impl_three_way_comparison >= 201907L +#if __cpp_impl_three_way_comparison >= 201907L \ + && ! defined _GLIBCXX_EH_PTR_COMPAT friend bool operator==(const exception_ptr&, const exception_ptr&) noexcept = default; #else - friend bool + friend _GLIBCXX_EH_PTR_USED bool operator==(const exception_ptr& __x, const exception_ptr& __y) _GLIBCXX_USE_NOEXCEPT { return __x._M_exception_object == __y._M_exception_object; } - friend bool + friend _GLIBCXX_EH_PTR_USED bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _GLIBCXX_USE_NOEXCEPT { return __x._M_exception_object != __y._M_exception_object; } @@ -170,25 +173,30 @@ namespace std __attribute__ ((__pure__)); }; -#ifndef _GLIBCXX_EH_PTR_COMPAT + _GLIBCXX_EH_PTR_USED +#ifndef _GLIBCXX_EH_PTR_COMPAT + __attribute__((__always_inline__)) // XXX see PR 97729 inline #endif exception_ptr::exception_ptr() _GLIBCXX_NOEXCEPT : _M_exception_object(0) { } -#ifndef _GLIBCXX_EH_PTR_COMPAT + _GLIBCXX_EH_PTR_USED +#ifndef _GLIBCXX_EH_PTR_COMPAT + __attribute__((__always_inline__)) inline #endif - exception_ptr::exception_ptr(const exception_ptr& __other) - _GLIBCXX_NOEXCEPT + exception_ptr::exception_ptr(const exception_ptr& __other) _GLIBCXX_NOEXCEPT : _M_exception_object(__other._M_exception_object) { if (_M_exception_object) _M_addref(); } -#ifndef _GLIBCXX_EH_PTR_COMPAT + _GLIBCXX_EH_PTR_USED +#ifndef _GLIBCXX_EH_PTR_COMPAT + __attribute__((__always_inline__)) inline #endif exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT @@ -197,20 +205,16 @@ namespace std _M_release(); } -#ifndef _GLIBCXX_EH_PTR_COMPAT - inline -#endif - exception_ptr& + _GLIBCXX_EH_PTR_USED + inline exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT { exception_ptr(__other).swap(*this); return *this; } -#ifndef _GLIBCXX_EH_PTR_COMPAT - inline -#endif - void + _GLIBCXX_EH_PTR_USED + inline void exception_ptr::swap(exception_ptr &__other) _GLIBCXX_USE_NOEXCEPT { void *__tmp = _M_exception_object; @@ -218,16 +222,6 @@ namespace std __other._M_exception_object = __tmp; } -#ifdef _GLIBCXX_EH_PTR_COMPAT - bool - operator==(const exception_ptr&, const exception_ptr&) - _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); - - bool - operator!=(const exception_ptr&, const exception_ptr&) - _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); -#endif - /// @relates exception_ptr inline void swap(exception_ptr& __lhs, exception_ptr& __rhs) @@ -276,6 +270,8 @@ namespace std #endif } +#undef _GLIBCXX_EH_PTR_USED + // @} group exceptions } // namespace std --MSd2ShuMixI0uVaZ--