From patchwork Tue Apr 2 17:52:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1918933 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=GqwIMQcF; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4V8Fpx5CmKz1yZ3 for ; Wed, 3 Apr 2024 04:53:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 92E293858CDA for ; Tue, 2 Apr 2024 17:53:09 +0000 (GMT) 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 016A73858D28 for ; Tue, 2 Apr 2024 17:52:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 016A73858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 016A73858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712080367; cv=none; b=ordMH3hUAfalL4pQZ8VhX80FJinw0aNrkF9BE5P1BvAfQ/yLoQiLiM8iFbxFQ0xVQk34vOn4AWMW+eza6pc+z8lLfCW8NcloUCjYlejQVL18NyXFplfDsZ5GuOMIr8IAHUy1XLc8TU2OuUI80yCYpis6Wq184tay5ufDubp0/Bw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712080367; c=relaxed/simple; bh=8M8iHftlDBMyKUlP9wXDQsrMBRiaPk3cqNvV17OTz1g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=YHPDd5CnYWVXdEHWlJ1wz5K+/6IT82h5pMwD7mu+3czt7X7R9nFrGpn+xDb3qxNP5wGwuSP/VtoZKJVJnkLve9zPupb/SZg91g+sqo9TUFYI/A+7z0nLLxgoLOOFATF2EruHbHVh4BxA9jSzIudyd/u6Dp6b9niC4zpCq4yiS0o= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712080364; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rmRbxTXBxRk5FpTh5l4svdrdvASeaMYhnAMiTgJWHLE=; b=GqwIMQcFfJuA5hsbkXBQGAcCccaokwEzNmKMgMDZbp99vKRskdWkUs5dCnjzwj8uO1G+8z h7w72XFB4GZ/22dkM9x4dj0+tsx0FmpxAxDIWAKrB9EeJwjhjqsZrjH+zq25AApcJa7jqY zdKVuKWbaYosCwdFkGsOLsU+HdzTWws= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-402-5EG694n4NQ-7Y6-ySHn2_Q-1; Tue, 02 Apr 2024 13:52:43 -0400 X-MC-Unique: 5EG694n4NQ-7Y6-ySHn2_Q-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D5D1A38049F0 for ; Tue, 2 Apr 2024 17:52:42 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.17.207]) by smtp.corp.redhat.com (Postfix) with ESMTP id AFD442166B31; Tue, 2 Apr 2024 17:52:42 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Cc: Jakub Jelinek Subject: [PATCH] c++: constexpr error with fn redecl in local scope [PR111132] Date: Tue, 2 Apr 2024 13:52:37 -0400 Message-ID: <20240402175237.482119-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.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_H4, RCVD_IN_MSPIKE_WL, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/13? -- >8 -- We evaluate constexpr functions on the original, pre-genericization bodies. That means that the function body we're evaluating will not have gone through cp_genericize_r's "Map block scope extern declarations to visible declarations with the same name and type in outer scopes if any". Here: constexpr bool bar() { return true; } // #1 constexpr bool foo() { constexpr bool bar(void); // #2 return bar(); } it means that we: 1) register_constexpr_fundef (#1) 2) cp_genericize (#1) nothing interesting happens 3) register_constexpr_fundef (foo) does copy_fn, so we have two copies of the BIND_EXPR 4) cp_genericize (foo) this remaps #2 to #1, but only on one copy of the BIND_EXPR 5) retrieve_constexpr_fundef (foo) we find it, no problem 6) retrieve_constexpr_fundef (#2) and here #2 isn't found in constexpr_fundef_table, because we're working on the BIND_EXPR copy where #2 wasn't mapped to #1 so we fail. We've only registered #1. It should work to use DECL_LOCAL_DECL_ALIAS (which used to be extern_decl_map). We evaluate constexpr functions on pre-cp_fold bodies to avoid diagnostic problems, but the remapping I'm proposing should not interfere with diagnostics. This is not a problem for a global scope redeclaration; there we go through duplicate_decls which keeps the DECL_UID: DECL_UID (olddecl) = olddecl_uid; and DECL_UID is what constexpr_fundef_hasher::hash uses. PR c++/111132 gcc/cp/ChangeLog: * constexpr.cc (get_function_named_in_call): If there's a DECL_LOCAL_DECL_ALIAS, use it. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-redeclaration3.C: New test. * g++.dg/cpp0x/constexpr-redeclaration4.C: New test. --- gcc/cp/constexpr.cc | 19 +++++++++++++++---- .../g++.dg/cpp0x/constexpr-redeclaration3.C | 13 +++++++++++++ .../g++.dg/cpp0x/constexpr-redeclaration4.C | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C base-commit: 0e64bbb8823f7b3757befc878ed177dfb59943d1 diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index fa346fe01c9..b47f0e984c0 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -702,15 +702,26 @@ build_constexpr_constructor_member_initializers (tree type, tree body) /* We have an expression tree T that represents a call, either CALL_EXPR or AGGR_INIT_EXPR. If the call is lexically to a named function, - retrun the _DECL for that function. */ + return the _DECL for that function. */ static tree get_function_named_in_call (tree t) { tree fun = cp_get_callee (t); - if (fun && TREE_CODE (fun) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL) - fun = TREE_OPERAND (fun, 0); + if (fun) + { + if (TREE_CODE (fun) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL) + fun = TREE_OPERAND (fun, 0); + /* We evaluate constexpr functions on the original, pre-genericization + bodies. So block-scope extern declarations have not been mapped to + declarations in outer scopes. Use the namespace-scope declaration, + if any, so that retrieve_constexpr_fundef can find it (PR111132). */ + if (TREE_CODE (fun) == FUNCTION_DECL && DECL_LOCAL_DECL_P (fun)) + if (tree alias = DECL_LOCAL_DECL_ALIAS (fun)) + if (alias != error_mark_node) + fun = alias; + } return fun; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C new file mode 100644 index 00000000000..2b41b456fc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C @@ -0,0 +1,13 @@ +// PR c++/111132 +// { dg-do compile { target c++11 } } + +constexpr bool bar(void) { + return true; +} + +constexpr bool foo() { + constexpr bool bar(void); + return bar(); +} + +static_assert(foo(), ""); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C new file mode 100644 index 00000000000..c58247218c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C @@ -0,0 +1,14 @@ +// PR c++/111132 +// { dg-do compile { target c++11 } } + +constexpr bool bar(void) { + return true; +} + +constexpr bool bar(void); + +constexpr bool foo() { + return bar(); +} + +static_assert(foo(), "");