From patchwork Mon Jun 14 20:18:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1491848 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=N4ytc10u; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G3jTd3nXyz9sWD for ; Tue, 15 Jun 2021 06:19:16 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9A5CA396E85F for ; Mon, 14 Jun 2021 20:19:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9A5CA396E85F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1623701953; bh=jQK/HYYXwLCn1OlJF8AtsInaOA8uCVGoJQloU94fLK0=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=N4ytc10ujIjtFnjXwv4X+W5ywANkX9nAyrntqOaf4KXKLfhRloMtlRC5e4vnb+Yu4 qFs0SF8upJjfFd53kDeZa4thhwArNa1vpDE/qEUt3irTRjkxbDWN5I4b/X0JpDa9Cw Py9hszQb3h1U707Xizhng/LVIOAITxrloUNnrpcY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 D4608396E855 for ; Mon, 14 Jun 2021 20:18:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D4608396E855 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-476-EBY58XtnOPCF3d7HWqmHVg-1; Mon, 14 Jun 2021 16:18:08 -0400 X-MC-Unique: EBY58XtnOPCF3d7HWqmHVg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8AEA4803622; Mon, 14 Jun 2021 20:18:07 +0000 (UTC) Received: from localhost (unknown [10.33.36.175]) by smtp.corp.redhat.com (Postfix) with ESMTP id 295B860C0F; Mon, 14 Jun 2021 20:18:06 +0000 (UTC) Date: Mon, 14 Jun 2021 21:18:06 +0100 To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Fix common_reference for non-reference results [PR100894] Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-14.6 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, URI_HEX 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-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The result of COMMON-REF(A&, B&&) where they have no common reference type should not be a reference. The implementation of COMMON-REF fails to check that the result is a reference, so is well-formed when it shouldn't be. This means that common_reference uses that result when it shouldn't. The fix is to reject the result of COMMON-REF(A, B) if it's not a reference, so that common_reference falls through to the next case, which uses COND-RES, which yields a non-reference result. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: PR libstdc++/100894 * include/std/type_traits (__common_ref_impl): Only use the type if it's a reference. * testsuite/20_util/common_reference/100894.cc: New test. Tested powerpc64le-linux. Committed to trunk. commit c37b5ddcc88e0cc0f6a4ad609eda51021df0f6bb Author: Jonathan Wakely Date: Mon Jun 14 20:31:00 2021 libstdc++: Fix common_reference for non-reference results [PR100894] The result of COMMON-REF(A&, B&&) where they have no common reference type should not be a reference. The implementation of COMMON-REF fails to check that the result is a reference, so is well-formed when it shouldn't be. This means that common_reference uses that result when it shouldn't. The fix is to reject the result of COMMON-REF(A, B) if it's not a reference, so that common_reference falls through to the next case, which uses COND-RES, which yields a non-reference result. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: PR libstdc++/100894 * include/std/type_traits (__common_ref_impl): Only use the type if it's a reference. * testsuite/20_util/common_reference/100894.cc: New test. diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index eaf06fcb036..d9068a06f08 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -3340,11 +3340,17 @@ template template using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type; + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) + template + using __condres_cvref + = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; + // If A and B are both lvalue reference types, ... template - struct __common_ref_impl<_Xp&, _Yp&, - __void_t<__cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>>> - { using type = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; }; + struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>> + : enable_if>, + __condres_cvref<_Xp, _Yp>> + { }; // let C be remove_reference_t&& template diff --git a/libstdc++-v3/testsuite/20_util/common_reference/100894.cc b/libstdc++-v3/testsuite/20_util/common_reference/100894.cc new file mode 100644 index 00000000000..5e144768002 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/common_reference/100894.cc @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++20" } +// { dg-do compile { target c++20 } } +// PR libstdc++/100894 - common_reference implementation seems to be wrong + +#include + +struct A {}; +struct B { B(A); }; +static_assert( std::is_same_v, B> );