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 D35C83857C52 for ; Sat, 10 Oct 2020 10:52:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D35C83857C52 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-4-Ew9cvRYuMBuV6eYbkwLG4Q-1; Sat, 10 Oct 2020 06:52:34 -0400 X-MC-Unique: Ew9cvRYuMBuV6eYbkwLG4Q-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 D2AC2805F06; Sat, 10 Oct 2020 10:52:33 +0000 (UTC) Received: from localhost (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5F9A85C1C7; Sat, 10 Oct 2020 10:52:33 +0000 (UTC) Date: Sat, 10 Oct 2020 11:52:32 +0100 From: Jonathan Wakely To: Ville Voutilainen Cc: libstdc++ , gcc-patches List Subject: Re: [PATCH] libstdc++: Diagnose visitors with different return types [PR95904] Message-ID: <20201010105232.GS7004@redhat.com> References: <20200929112043.GL3946@redhat.com> <20201002221434.GC3426@redhat.com> MIME-Version: 1.0 In-Reply-To: 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: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline X-Spam-Status: No, score=-13.3 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=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Oct 2020 10:52:40 -0000 On 05/10/20 22:35 +0300, Ville Voutilainen via Libstdc++ wrote: >On Mon, 5 Oct 2020 at 01:15, Ville Voutilainen > wrote: >> The patch is borked, doesn't pass tests, fixing... > >Unborked, ok for trunk if full testsuite passes? > >2020-10-05 Ville Voutilainen > > PR libstdc++/95904 > * include/std/variant (__deduce_visit_result): Add a nested ::type. > (__gen_vtable_impl::_S_apply): > Check the visitor return type. > (__same_types): New. > (__check_visitor_result): Likewise. > (__check_visitor_results): Likewise. > (visit(_Visitor&&, _Variants&&...)): Use __check_visitor_results > in case we're visiting just one variant. > * testsuite/20_util/variant/visit_neg.cc: Adjust. >diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant >index dd8847cf829..b32e564fd41 100644 >--- a/libstdc++-v3/include/std/variant >+++ b/libstdc++-v3/include/std/variant >@@ -182,7 +182,7 @@ namespace __variant > // used for raw visitation with indices passed in > struct __variant_idx_cookie { using type = __variant_idx_cookie; }; > // Used to enable deduction (and same-type checking) for std::visit: >- template struct __deduce_visit_result { }; >+ template struct __deduce_visit_result { using type = _Tp; }; > > // Visit variants that might be valueless. > template >@@ -1017,7 +1017,26 @@ namespace __variant > > static constexpr auto > _S_apply() >- { return _Array_type{&__visit_invoke}; } >+ { >+ if constexpr (_Array_type::__result_is_deduced::value) >+ { >+ constexpr bool __visit_ret_type_mismatch = >+ !is_same_v+ decltype(__visit_invoke(std::declval<_Visitor>(), >+ std::declval<_Variants>()...))>; >+ if constexpr (__visit_ret_type_mismatch) >+ { >+ static_assert(!__visit_ret_type_mismatch, >+ "std::visit requires the visitor to have the same " >+ "return type for all alternatives of a variant"); >+ return __nonesuch{}; >+ } >+ else >+ return _Array_type{&__visit_invoke}; >+ } >+ else >+ return _Array_type{&__visit_invoke}; >+ } > }; > > template >@@ -1692,6 +1711,26 @@ namespace __variant > std::forward<_Variants>(__variants)...); > } > >+ template >+ constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...); >+ >+ template >+ decltype(auto) >+ __check_visitor_result(_Visitor&& __vis, _Variant&& __variant) >+ { >+ return std::__invoke(std::forward<_Visitor>(__vis), >+ std::get<_Idx>(std::forward<_Variant>(__variant))); >+ } >+ >+ template index_sequence uses size_t not unsigned long. This parameter pack needs to be size_t... _Idxs, and the NTTP for __check_visitor_result should be size_t _Idx.