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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 87AA1398B179 for ; Tue, 27 Apr 2021 13:10:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 87AA1398B179 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-414-7NKBm4sNMZ21acGWE0nl5w-1; Tue, 27 Apr 2021 09:10:11 -0400 X-MC-Unique: 7NKBm4sNMZ21acGWE0nl5w-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 029A6108C30A; Tue, 27 Apr 2021 13:10:11 +0000 (UTC) Received: from localhost (unknown [10.33.36.164]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9411B6A036; Tue, 27 Apr 2021 13:10:10 +0000 (UTC) Date: Tue, 27 Apr 2021 14:10:09 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Define net::socket_base::message_flags operators as friends [PR 100285] Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="FJzqWl4Nlf/SYC5o" Content-Disposition: inline X-Spam-Status: No, score=-14.1 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_LOW, RCVD_IN_MSPIKE_H4, 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: Tue, 27 Apr 2021 13:10:18 -0000 --FJzqWl4Nlf/SYC5o Content-Type: text/plain; charset=us-ascii Content-Disposition: inline The overloaded operators for socket_base::message_flags should only be defined when the message_flags type itself is defined. Rather than duplicate the preprocessor conditional, this moves the operators into the same scope as the type, defining them as hidden friends. As well as fixing the bug, this has all the usual advantages of hidden friends (they are not visible to normal name lookup for unrelated types). For consistency, do the same for the resolver_base::flags bitmask operators too. libstdc++-v3/ChangeLog: PR libstdc++/100285 * include/experimental/internet (resolver_base::flags): Define overloaded operators as hidden friends. * include/experimental/socket (socket_base::message_flags): Likewise. Tested x86_64-linux. Committed to trunk. --FJzqWl4Nlf/SYC5o Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 8aadb4fedb17e7a44583a7a5a4e96b1874e1ce98 Author: Jonathan Wakely Date: Tue Apr 27 11:07:47 2021 libstdc++: Define net::socket_base::message_flags operators as friends [PR 100285] The overloaded operators for socket_base::message_flags should only be defined when the message_flags type itself is defined. Rather than duplicate the preprocessor conditional, this moves the operators into the same scope as the type, defining them as hidden friends. As well as fixing the bug, this has all the usual advantages of hidden friends (they are not visible to normal name lookup for unrelated types). For consistency, do the same for the resolver_base::flags bitmask operators too. libstdc++-v3/ChangeLog: PR libstdc++/100285 * include/experimental/internet (resolver_base::flags): Define overloaded operators as hidden friends. * include/experimental/socket (socket_base::message_flags): Likewise. diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet index 2e3fd06ead2..11961762880 100644 --- a/libstdc++-v3/include/experimental/internet +++ b/libstdc++-v3/include/experimental/internet @@ -1660,39 +1660,39 @@ namespace ip static constexpr flags all_matching = (flags)AI_ALL; static constexpr flags address_configured = (flags)AI_ADDRCONFIG; + friend constexpr flags + operator&(flags __f1, flags __f2) noexcept + { return flags( int(__f1) & int(__f2) ); } + + friend constexpr flags + operator|(flags __f1, flags __f2) noexcept + { return flags( int(__f1) | int(__f2) ); } + + friend constexpr flags + operator^(flags __f1, flags __f2) noexcept + { return flags( int(__f1) ^ int(__f2) ); } + + friend constexpr flags + operator~(flags __f) noexcept + { return flags( ~int(__f) ); } + + friend constexpr flags& + operator&=(flags& __f1, flags __f2) noexcept + { return __f1 = (__f1 & __f2); } + + friend constexpr flags& + operator|=(flags& __f1, flags __f2) noexcept + { return __f1 = (__f1 | __f2); } + + friend constexpr flags& + operator^=(flags& __f1, flags __f2) noexcept + { return __f1 = (__f1 ^ __f2); } + protected: resolver_base() = default; ~resolver_base() = default; }; - constexpr resolver_base::flags - operator&(resolver_base::flags __f1, resolver_base::flags __f2) noexcept - { return resolver_base::flags( int(__f1) & int(__f2) ); } - - constexpr resolver_base::flags - operator|(resolver_base::flags __f1, resolver_base::flags __f2) noexcept - { return resolver_base::flags( int(__f1) | int(__f2) ); } - - constexpr resolver_base::flags - operator^(resolver_base::flags __f1, resolver_base::flags __f2) noexcept - { return resolver_base::flags( int(__f1) ^ int(__f2) ); } - - constexpr resolver_base::flags - operator~(resolver_base::flags __f) noexcept - { return resolver_base::flags( ~int(__f) ); } - - constexpr resolver_base::flags& - operator&=(resolver_base::flags& __f1, resolver_base::flags __f2) noexcept - { return __f1 = (__f1 & __f2); } - - constexpr resolver_base::flags& - operator|=(resolver_base::flags& __f1, resolver_base::flags __f2) noexcept - { return __f1 = (__f1 | __f2); } - - constexpr resolver_base::flags& - operator^=(resolver_base::flags& __f1, resolver_base::flags __f2) noexcept - { return __f1 = (__f1 ^ __f2); } - // TODO define resolver_base::flags static constants in .so for C++14 mode /// @} diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket index 18849f607f8..bf6a8c87e67 100644 --- a/libstdc++-v3/include/experimental/socket +++ b/libstdc++-v3/include/experimental/socket @@ -319,13 +319,38 @@ inline namespace v1 = (message_flags)MSG_DONTROUTE; static const int max_listen_connections = SOMAXCONN; -#endif + + // message_flags bitmask operations are defined as hidden friends. + + friend constexpr message_flags + operator&(message_flags __f1, message_flags __f2) noexcept + { return message_flags( int(__f1) & int(__f2) ); } + + friend constexpr message_flags + operator|(message_flags __f1, message_flags __f2) noexcept + { return message_flags( int(__f1) | int(__f2) ); } + + friend constexpr message_flags + operator^(message_flags __f1, message_flags __f2) noexcept + { return message_flags( int(__f1) ^ int(__f2) ); } + + friend constexpr message_flags + operator~(message_flags __f) noexcept + { return message_flags( ~int(__f) ); } + + friend constexpr message_flags& + operator&=(message_flags& __f1, message_flags __f2) noexcept + { return __f1 = (__f1 & __f2); } + + friend constexpr message_flags& + operator|=(message_flags& __f1, message_flags __f2) noexcept + { return __f1 = (__f1 | __f2); } + + friend constexpr message_flags& + operator^=(message_flags& __f1, message_flags __f2) noexcept + { return __f1 = (__f1 ^ __f2); } protected: - socket_base() = default; - ~socket_base() = default; - -#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H struct __msg_hdr : ::msghdr { #ifdef IOV_MAX @@ -382,43 +407,12 @@ inline namespace v1 } }; #endif + + protected: + socket_base() = default; + ~socket_base() = default; }; - constexpr socket_base::message_flags - operator&(socket_base::message_flags __f1, socket_base::message_flags __f2) - noexcept - { return socket_base::message_flags( int(__f1) & int(__f2) ); } - - constexpr socket_base::message_flags - operator|(socket_base::message_flags __f1, socket_base::message_flags __f2) - noexcept - { return socket_base::message_flags( int(__f1) | int(__f2) ); } - - constexpr socket_base::message_flags - operator^(socket_base::message_flags __f1, socket_base::message_flags __f2) - noexcept - { return socket_base::message_flags( int(__f1) ^ int(__f2) ); } - - constexpr socket_base::message_flags - operator~(socket_base::message_flags __f) - noexcept - { return socket_base::message_flags( ~int(__f) ); } - - constexpr socket_base::message_flags& - operator&=(socket_base::message_flags& __f1, socket_base::message_flags __f2) - noexcept - { return __f1 = (__f1 & __f2); } - - constexpr socket_base::message_flags& - operator|=(socket_base::message_flags& __f1, socket_base::message_flags __f2) - noexcept - { return __f1 = (__f1 | __f2); } - - constexpr socket_base::message_flags& - operator^=(socket_base::message_flags& __f1, socket_base::message_flags __f2) - noexcept - { return __f1 = (__f1 ^ __f2); } - // TODO define socket_base static constants in .so for C++14 mode #if _GLIBCXX_HAVE_UNISTD_H --FJzqWl4Nlf/SYC5o--