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.129.124]) by sourceware.org (Postfix) with ESMTPS id 8C733385782B for ; Fri, 3 Mar 2023 17:51:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8C733385782B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1677865895; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CidkZgprcJ106kHXo7xg3wPMAoFZIEd6OyVGuy8ihoI=; b=Shbo+vZC+KPrxYDH2PxFz7Tvq6EWOQw+WzoMY+xRiZsZluOKT5UomQcdlJzUrdYl/OqWPV 36dNXupaVoLecsoDacoxgnzcvlYAxSs5tpv7vwJ3GXfg3QMQ/HwYbhjeTJ3nawZMjcy/U/ VO3+Ft6tpXt1fS0MQdS08Y39uoTntio= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-547-GkGE9HTpPk-q9zdrN7zO8Q-1; Fri, 03 Mar 2023 12:51:24 -0500 X-MC-Unique: GkGE9HTpPk-q9zdrN7zO8Q-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7BD1D100F92E for ; Fri, 3 Mar 2023 17:51:24 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.9.114]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4E3D22026D4B; Fri, 3 Mar 2023 17:51:24 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Subject: [PATCH] c++: error with constexpr operator() [PR107939] Date: Fri, 3 Mar 2023 12:51:21 -0500 Message-Id: <20230303175121.705791-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-12.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_NONE,RCVD_IN_MSPIKE_H2,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 List-Id: Similarly to PR107938, this also started with r11-557, whereby cp_finish_decl can call check_initializer even in a template for a constexpr initializer. Here we are rejecting extern const Q q; template constexpr auto p = q(0); even though q has a constexpr operator(). It's deemed non-const by decl_maybe_constant_var_p because even though 'q' is const it is not of integral/enum type. I think the fix is for p_c_e to treat q(0) as potentially-constant, as below. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/12? PR c++/107939 gcc/cp/ChangeLog: * constexpr.cc (is_constexpr_function_object): New. (potential_constant_expression_1): Treat an object with constexpr operator() as potentially-constant. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/var-templ74.C: Remove dg-error. * g++.dg/cpp1y/var-templ77.C: New test. --- gcc/cp/constexpr.cc | 23 ++++++++++++++++++++++- gcc/testsuite/g++.dg/cpp1y/var-templ74.C | 2 +- gcc/testsuite/g++.dg/cpp1y/var-templ77.C | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ77.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index acf9847a4d1..7d786f332b4 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8929,6 +8929,24 @@ check_for_return_continue (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } +/* Return true iff TYPE is a class with constexpr operator(). */ + +static bool +is_constexpr_function_object (tree type) +{ + if (!CLASS_TYPE_P (type)) + return false; + + for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f)) + if (TREE_CODE (f) == FUNCTION_DECL + && DECL_OVERLOADED_OPERATOR_P (f) + && DECL_OVERLOADED_OPERATOR_IS (f, CALL_EXPR) + && DECL_DECLARED_CONSTEXPR_P (f)) + return true; + + return false; +} + /* Return true if T denotes a potentially constant expression. Issue diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true, an lvalue-rvalue conversion is implied. If NOW is true, we want to @@ -9160,7 +9178,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, } else if (fun) { - if (RECUR (fun, rval)) + if (VAR_P (fun) + && is_constexpr_function_object (TREE_TYPE (fun))) + /* Could be an object with constexpr operator(). */; + else if (RECUR (fun, rval)) /* Might end up being a constant function pointer. */; else return false; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ74.C b/gcc/testsuite/g++.dg/cpp1y/var-templ74.C index 4e2e800a6eb..c76a7d949ac 100644 --- a/gcc/testsuite/g++.dg/cpp1y/var-templ74.C +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ74.C @@ -9,7 +9,7 @@ struct Q { extern const Q q; template -constexpr const Q* p = q(0); // { dg-bogus "not usable" "PR107939" { xfail *-*-* } } +constexpr const Q* p = q(0); void g () diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ77.C b/gcc/testsuite/g++.dg/cpp1y/var-templ77.C new file mode 100644 index 00000000000..b480f54b001 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ77.C @@ -0,0 +1,14 @@ +// PR c++/107939 +// { dg-do compile { target c++14 } } + +struct Q { + struct P { + const Q* p; + }; + int n; + constexpr P operator()(int) const { return {this}; } +}; + +extern const Q q; +template +constexpr auto p = q(0); base-commit: 9056d0df830c5a295d7594d517d409d10476990d -- 2.39.2