From patchwork Mon Sep 26 16:25:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 58046 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 577BA3857415 for ; Mon, 26 Sep 2022 16:26:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 577BA3857415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664209571; bh=AltRwmfFgU73v2TksjrGnJAClgboUQ1KYoVfEjbw6UI=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=C44K79EH877T03bUSBJtx2XtCVCyfP2OPrzixOahzPkL2HhELmx9WzUPm8MiHvAac uIDukGMyaLaaJ9ON53NqIYzdF4E5djODXikwcOEQ/ORv9b856sYtmMor29LLy9Ja// c7Vwi8gvbX/ilK878Im4SKtYcfCaw1ckNPmbsjko= 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 ESMTPS id 951973858C62 for ; Mon, 26 Sep 2022 16:25:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 951973858C62 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-614-2UufY0ReOZiOfLvahGgJOg-1; Mon, 26 Sep 2022 12:25:41 -0400 X-MC-Unique: 2UufY0ReOZiOfLvahGgJOg-1 Received: by mail-qk1-f198.google.com with SMTP id bl17-20020a05620a1a9100b006cdf19243acso5316443qkb.4 for ; Mon, 26 Sep 2022 09:25:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date; bh=AltRwmfFgU73v2TksjrGnJAClgboUQ1KYoVfEjbw6UI=; b=ZC1xA8s5nA2l4QtTWnPBNIPVGRnM7IYHmUD4aCmq2hndEUJiu1M7tMvrpxtzXQ7LK4 oPylnRbKHkvvOtvG2HqH+sH9Pcyq8//ikYpqHb16t0ftLDOvDk9SkIDw5CBQABXBM2TB Nhih3Vr6GVETWf9p1dihEcfKuhAJ/qAO0B6tAT8XPtfwTODg/KsgNf3ioEaFxAp1ZYAC ABIZoFhTTxZuYVhBU6cb55v+Zev2yMBkqi65rzdEmcUKZDsg+YpzUx3Tn8D7zeUMSvQA EtihqN6yIltmRjxZmCjEbjnH9821lQTbXSZIADQpHKDRZuRWXyEDrp/2IYyxUBMgEkkz v2dg== X-Gm-Message-State: ACrzQf2Ssr47NP/s9g1wJFXHF8wKM/CLnbtWlqxx45Y1gFMsTVOLud8/ AuG3mfvgG8YlQlqbRC7sQMHgpc2dD62hBfoKx2bs0bZ2rPjjWhGZVaaw6QEAXjtd8wvxYXW41Cy infrJlURRO3zEjmjKrg== X-Received: by 2002:ac8:5b0e:0:b0:35c:bae7:d9eb with SMTP id m14-20020ac85b0e000000b0035cbae7d9ebmr18757396qtw.681.1664209539634; Mon, 26 Sep 2022 09:25:39 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5jZM7JRLKIDOzh2H6cQxX4T1Ym8TrL4+htz3WXiNdgXrvqdOdcLbgmzFRVJvjNYfodr+99/w== X-Received: by 2002:ac8:5b0e:0:b0:35c:bae7:d9eb with SMTP id m14-20020ac85b0e000000b0035cbae7d9ebmr18757367qtw.681.1664209539244; Mon, 26 Sep 2022 09:25:39 -0700 (PDT) Received: from redhat.com (2603-7000-9500-2e39-0000-0000-0000-1db4.res6.spectrum.com. [2603:7000:9500:2e39::1db4]) by smtp.gmail.com with ESMTPSA id s14-20020a05620a29ce00b006ce60f5d8e4sm12492961qkp.130.2022.09.26.09.25.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Sep 2022 09:25:38 -0700 (PDT) Date: Mon, 26 Sep 2022 12:25:36 -0400 To: Patrick Palka Subject: [PATCH v2] c++: Instantiate less when evaluating __is_convertible Message-ID: References: <20220926152258.20921-1-polacek@redhat.com> <22a3074f-0180-5ab6-5a9d-c27f8db507c7@idea> MIME-Version: 1.0 In-Reply-To: <22a3074f-0180-5ab6-5a9d-c27f8db507c7@idea> User-Agent: Mutt/2.2.7 (2022-08-07) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-11.9 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, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Cc: Jonathan Wakely , GCC Patches Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" On Mon, Sep 26, 2022 at 11:51:30AM -0400, Patrick Palka wrote: > On Mon, 26 Sep 2022, Marek Polacek via Gcc-patches wrote: > > > Jon reported that evaluating __is_convertible in this test leads to > > instantiating char_traits::eq, which is invalid (because we > > are trying to call a member function on a char) and so we fail to > > compile the test. __is_convertible doesn't and shouldn't need to > > instantiate so much, so let's limit it with a cp_unevaluated guard. > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > PR c++/106784 > > > > gcc/cp/ChangeLog: > > > > * method.cc (is_convertible): Use cp_unevaluated. > > I think is_nothrow_convertible would need cp_unevaluated too (or maybe we > should define is_nothrow_convertible in terms of is_convertible). /facepalm, that's what I get by not using a single implementation for both! > And the testcase can probably be minimized to something like: > > struct A; > struct B { template B(const T&) noexcept { T::nonexistent; } }; > > static_assert(__is_convertible(const A&, B)); > static_assert(__is_nothrow_convertible(const A&, B)); Adjusted, thanks. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >8 -- Jon reported that evaluating __is_convertible in a test led to instantiating something ill-formed and so we failed to compile the test. __is_convertible doesn't and shouldn't need to instantiate so much, so let's limit it with a cp_unevaluated guard. Use a helper function to implement both built-ins. PR c++/106784 gcc/cp/ChangeLog: * method.cc (is_convertible_helper): New. (is_convertible): Use it. (is_nothrow_convertible): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/is_convertible3.C: New test. * g++.dg/ext/is_nothrow_convertible3.C: New test. --- gcc/cp/method.cc | 23 ++++++++++++------- gcc/testsuite/g++.dg/ext/is_convertible3.C | 9 ++++++++ .../g++.dg/ext/is_nothrow_convertible3.C | 9 ++++++++ 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_convertible3.C create mode 100644 gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C base-commit: 099a66498bf7a40764002793eba66c881a251b76 diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index c35a59fe56c..9f917f13134 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -2236,6 +2236,19 @@ ref_xes_from_temporary (tree to, tree from, bool direct_init_p) return ref_conv_binds_directly (to, val, direct_init_p).is_false (); } +/* Worker for is_{,nothrow_}convertible. Attempt to perform an implicit + conversion from FROM to TO and return the result. */ + +static tree +is_convertible_helper (tree from, tree to) +{ + if (VOID_TYPE_P (from) && VOID_TYPE_P (to)) + return integer_one_node; + cp_unevaluated u; + tree expr = build_stub_object (from); + return perform_implicit_conversion (to, expr, tf_none); +} + /* Return true if FROM can be converted to TO using implicit conversions, or both FROM and TO are possibly cv-qualified void. NB: This doesn't implement the "Access checks are performed as if from a context unrelated @@ -2244,10 +2257,7 @@ ref_xes_from_temporary (tree to, tree from, bool direct_init_p) bool is_convertible (tree from, tree to) { - if (VOID_TYPE_P (from) && VOID_TYPE_P (to)) - return true; - tree expr = build_stub_object (from); - expr = perform_implicit_conversion (to, expr, tf_none); + tree expr = is_convertible_helper (from, to); if (expr == error_mark_node) return false; return !!expr; @@ -2258,10 +2268,7 @@ is_convertible (tree from, tree to) bool is_nothrow_convertible (tree from, tree to) { - if (VOID_TYPE_P (from) && VOID_TYPE_P (to)) - return true; - tree expr = build_stub_object (from); - expr = perform_implicit_conversion (to, expr, tf_none); + tree expr = is_convertible_helper (from, to); if (expr == NULL_TREE || expr == error_mark_node) return false; return expr_noexcept_p (expr, tf_none); diff --git a/gcc/testsuite/g++.dg/ext/is_convertible3.C b/gcc/testsuite/g++.dg/ext/is_convertible3.C new file mode 100644 index 00000000000..7a986d075c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_convertible3.C @@ -0,0 +1,9 @@ +// PR c++/106784 +// { dg-do compile { target c++11 } } +// Make sure we don't reject this at runtime by trying to instantiate +// something that would be ill-formed. + +struct A; +struct B { template B(const T&) noexcept { T::nonexistent; } }; + +static_assert(__is_convertible(const A&, B), ""); diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C new file mode 100644 index 00000000000..05b1e1d9ad9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C @@ -0,0 +1,9 @@ +// PR c++/106784 +// { dg-do compile { target c++11 } } +// Make sure we don't reject this at runtime by trying to instantiate +// something that would be ill-formed. + +struct A; +struct B { template B(const T&) noexcept { T::nonexistent; } }; + +static_assert(__is_nothrow_convertible(const A&, B), "");