From patchwork Mon Aug 12 06:59:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 1971450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=JVCPtcBk; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; 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 [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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wj54X332Rz1yXl for ; Mon, 12 Aug 2024 17:00:10 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6A4ED3858408 for ; Mon, 12 Aug 2024 07:00:08 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by sourceware.org (Postfix) with ESMTPS id BE4C83858C31 for ; Mon, 12 Aug 2024 06:59:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BE4C83858C31 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BE4C83858C31 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::42d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1723445982; cv=none; b=MmHnFX+N5tRZbZfoxbYUZanazSqdZ6PiSIWkuih0W4NNifqQ0dAxWCWpdsvnIrK0QR7mz4l7+eshR8SKtgj8n4s96NquFXEho6doD2wt1HlXORh8B6egnAjSQvPRAYLB8KZpi0mH63JY09v+idhRPbd7i4LYckB1QrbnWPT2AOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1723445982; c=relaxed/simple; bh=itNuVVWtCVEz7AG7v+UsnlfRl+7WVUs7Ec/YxVkYL2c=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=MSuy/iKDefGxP4TTrsw1HuTvRMbnmN5NlqqRuW2HMpMPt45iM0RKb1YbE0xClHBqGaD+WGDQuJ3gF7lqp8tW0kSjpq+dnxrydayi4U5gmosG3cAGgNEdEQcaclwfl7lRAg4AulUADs+Poq1u70qhiBlG8rLPj99odBwmf8mrM8Q= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-710e39961f4so1067870b3a.3 for ; Sun, 11 Aug 2024 23:59:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723445979; x=1724050779; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=y3cccjq344RJV88cPv8wQnixp5RY9XArI6mxHwcMbVA=; b=JVCPtcBkHEhkt1/M5/0aPT+QJeNpsHKW56U1YH3VqXIwihTWYsIhqPqtO+f9HfEFkr kleLnYX+rOpg0VWAoHKzrijVcMW73n/PR+v5RmNwgvoJEIJ29/EYLAVIPT0uCunBuPiL eyYvbDeoaXJPIBYSR9nnk46+TiH6Yg8oXinladzB5YNLKChbmFhziXcrZ8jjlQAsV6Rh 1+YwdWHxmqKVRci/9VI6IHKJBgX9mAP1KUlofgpQKYjW51jbEFIOUEFfVN3TXQKoYwnU ztDPSSnpXlWf8Ur2gn3whlf33l/fdsZ6/e3qIYLr9SMK33OOpqOJ8WKVdrF/jWccYt7P wqUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723445979; x=1724050779; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=y3cccjq344RJV88cPv8wQnixp5RY9XArI6mxHwcMbVA=; b=kq7SSyknmm59xrx4UN5ry2oRXieqL7l2U6iARd+sfXOWDyU7cxEk95vZbz+MEynSBc ZnEUOL1l7LveZQqqijScdYU0cIpsZjFg0XxRPGHM0bPzIfgoghjSIabMQqRCuDBM5ToW vM4MQ3FkV2Wgb3gI7ZxpUMAs/oiePWjNHXNTqO/+95e8diUZduAfFwX7VEXkSSn9mfO2 5eWjnlPlf5JxiKuaJMzYc7xVFCQ+RgI+0mDDiUF8pHJ/SJS5sN80G1fViEiJoHlqRsgt UOuDnElqgT6dRH8NIh0/4G5c2/b6+9UExt1NNMQWxqB7MUnwaGW3j0bqUMPtiiH0/Muo GRFQ== X-Gm-Message-State: AOJu0YzqdAY8eQuRaKB8c4VFAwEOPFMbaJQpDcV5oIlJkPu5p/f4/HTE 8hPY2iG23B7iNhdDX3e0LPc9kK8uHT11V8/Jv+JmuUw+t+/snlzdoZamdQ== X-Google-Smtp-Source: AGHT+IH0LNN3HWcRQvR2LSfoKdhIYKtSr+QbczTpI2eBL6vE+6uN0PhCdPj5DekKiGigXbzktiU2yg== X-Received: by 2002:a05:6a00:17a5:b0:70e:a42e:3417 with SMTP id d2e1a72fcca58-710dc705e8amr5320393b3a.10.1723445978437; Sun, 11 Aug 2024 23:59:38 -0700 (PDT) Received: from Thaum. (110-174-164-242.static.tpgi.com.au. [110.174.164.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-710e5a89f52sm3333773b3a.162.2024.08.11.23.59.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 11 Aug 2024 23:59:38 -0700 (PDT) Message-ID: <66b9b2da.050a0220.2e8a84.8a49@mx.google.com> X-Google-Original-Message-ID: Date: Mon, 12 Aug 2024 16:59:33 +1000 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH] c++/modules: Merge default arguments [PR99274] MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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 and regtested on x86_64-pc-linux-gnu, OK for trunk? I tried to implement a remapping of the slots for TARGET_EXPRs for the FIXME but I wasn't able to work out how to do so effectively. Given that I doubt this will be a common issue I felt probably easiest to leave it for now and focus on other issues in the meantime; thoughts? The other thing to note is that most of this function just has a single error message always indicated by a 'goto mismatch;' but I felt that it seemed reasonable to provide more specific error messages where we can. But given that in the long term we probably want to replace this function with an appropriately enhanced 'duplicate_decls' anyway maybe it's not worth worrying about; this patch is still useful in the meantime if only for the testcases, I hope. -- >8 -- When merging a newly imported declaration with an existing declaration we don't currently propagate new default arguments, which causes issues when modularising header units. This patch adds logic to propagate default arguments to existing declarations on import, and error if the defaults do not match. PR c++/99274 gcc/cp/ChangeLog: * module.cc (trees_in::is_matching_decl): Merge default arguments. gcc/testsuite/ChangeLog: * g++.dg/modules/default-arg-1_a.H: New test. * g++.dg/modules/default-arg-1_b.C: New test. * g++.dg/modules/default-arg-2_a.H: New test. * g++.dg/modules/default-arg-2_b.C: New test. * g++.dg/modules/default-arg-3.h: New test. * g++.dg/modules/default-arg-3_a.H: New test. * g++.dg/modules/default-arg-3_b.C: New test. Signed-off-by: Nathaniel Shead Signed-off-by: Nathaniel Shead Reviewed-by: Patrick Palka Reviewed-by: Jason Merrill --- gcc/cp/module.cc | 62 ++++++++++++++++++- .../g++.dg/modules/default-arg-1_a.H | 17 +++++ .../g++.dg/modules/default-arg-1_b.C | 26 ++++++++ .../g++.dg/modules/default-arg-2_a.H | 17 +++++ .../g++.dg/modules/default-arg-2_b.C | 28 +++++++++ gcc/testsuite/g++.dg/modules/default-arg-3.h | 13 ++++ .../g++.dg/modules/default-arg-3_a.H | 5 ++ .../g++.dg/modules/default-arg-3_b.C | 6 ++ 8 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-1_a.H create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-1_b.C create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-2_a.H create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-2_b.C create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-3.h create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-3_a.H create mode 100644 gcc/testsuite/g++.dg/modules/default-arg-3_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index f4d137b13a1..87f34bac578 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11551,8 +11551,6 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) if (!same_type_p (TREE_VALUE (d_args), TREE_VALUE (e_args))) goto mismatch; - - // FIXME: Check default values } /* If EXISTING has an undeduced or uninstantiated exception @@ -11690,7 +11688,65 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) if (!DECL_EXTERNAL (d_inner)) DECL_EXTERNAL (e_inner) = false; - // FIXME: Check default tmpl and fn parms here + if (TREE_CODE (decl) == TEMPLATE_DECL) + { + /* Merge default template arguments. */ + tree d_parms = DECL_INNERMOST_TEMPLATE_PARMS (decl); + tree e_parms = DECL_INNERMOST_TEMPLATE_PARMS (existing); + gcc_checking_assert (TREE_VEC_LENGTH (d_parms) + == TREE_VEC_LENGTH (e_parms)); + for (int i = 0; i < TREE_VEC_LENGTH (d_parms); ++i) + { + tree d_default = TREE_PURPOSE (TREE_VEC_ELT (d_parms, i)); + tree& e_default = TREE_PURPOSE (TREE_VEC_ELT (e_parms, i)); + if (e_default == NULL_TREE) + e_default = d_default; + else if (d_default != NULL_TREE + && !cp_tree_equal (d_default, e_default)) + { + auto_diagnostic_group d; + tree d_parm = TREE_VALUE (TREE_VEC_ELT (d_parms, i)); + tree e_parm = TREE_VALUE (TREE_VEC_ELT (e_parms, i)); + error_at (DECL_SOURCE_LOCATION (d_parm), + "conflicting default argument for %#qD", d_parm); + inform (DECL_SOURCE_LOCATION (e_parm), + "existing default declared here"); + return false; + } + } + } + + if (TREE_CODE (d_inner) == FUNCTION_DECL) + { + /* Merge default function arguments. */ + tree d_parm = FUNCTION_FIRST_USER_PARMTYPE (d_inner); + tree e_parm = FUNCTION_FIRST_USER_PARMTYPE (e_inner); + int i = 0; + for (; d_parm && d_parm != void_list_node; + d_parm = TREE_CHAIN (d_parm), e_parm = TREE_CHAIN (e_parm), ++i) + { + tree d_default = TREE_PURPOSE (d_parm); + tree& e_default = TREE_PURPOSE (e_parm); + if (e_default == NULL_TREE) + e_default = d_default; + else if (d_default != NULL_TREE + && !cp_tree_equal (d_default, e_default) + /* FIXME: We need to remap the target to match the existing + parms so that cp_tree_equal works correctly, as with + break_out_target_exprs. */ + && !(TREE_CODE (d_default) == TARGET_EXPR + && TREE_CODE (e_default) == TARGET_EXPR)) + { + auto_diagnostic_group d; + error_at (get_fndecl_argument_location (d_inner, i), + "conflicting default argument for parameter %P of %#qD", + i, decl); + inform (get_fndecl_argument_location (e_inner, i), + "existing default declared here"); + return false; + } + } + } return true; } diff --git a/gcc/testsuite/g++.dg/modules/default-arg-1_a.H b/gcc/testsuite/g++.dg/modules/default-arg-1_a.H new file mode 100644 index 00000000000..65334930f74 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-1_a.H @@ -0,0 +1,17 @@ +// PR c++/99274 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +void f(int a, int b = 123); +template void g(T a, T b = {}); + +template struct A; +template struct B; + +struct S { + template void x(); + void y(int n = 123); +}; + +struct nontrivial { nontrivial(int); }; +void h(nontrivial p = nontrivial(123)); diff --git a/gcc/testsuite/g++.dg/modules/default-arg-1_b.C b/gcc/testsuite/g++.dg/modules/default-arg-1_b.C new file mode 100644 index 00000000000..80822896de1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-1_b.C @@ -0,0 +1,26 @@ +// PR c++/99274 +// { dg-additional-options "-fmodules-ts" } +// Propagate default args from import to existing decls + +void f(int a, int b); +template void g(T a, T b); +template struct A; +template struct B; +struct S { + template void x(); + void y(int n = 123); +}; +struct nontrivial { nontrivial(int); }; +void h(nontrivial p); + +import "default-arg-1_a.H"; + +template , typename = B> struct Q; + +int main() { + f(1); + g(2); + h(); + S{}.x(); + S{}.y(); +} diff --git a/gcc/testsuite/g++.dg/modules/default-arg-2_a.H b/gcc/testsuite/g++.dg/modules/default-arg-2_a.H new file mode 100644 index 00000000000..085d4c7f792 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-2_a.H @@ -0,0 +1,17 @@ +// PR c++/99274 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +void f(int a, int b = 123); +template void g(T a, T b = 123); + +template struct A; +template struct B; + +struct S { + template void x(); + void y(int n = 123); +}; + +struct nontrivial { nontrivial(int); }; +void h(nontrivial p = nontrivial(123)); diff --git a/gcc/testsuite/g++.dg/modules/default-arg-2_b.C b/gcc/testsuite/g++.dg/modules/default-arg-2_b.C new file mode 100644 index 00000000000..a6cc58738c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-2_b.C @@ -0,0 +1,28 @@ +// PR c++/99274 +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } +// Check for conflicting defaults. + +void f(int a, int b = 456); // { dg-message "existing default declared here" } + +template +void g(T a, T b = {}); // { dg-message "existing default declared here" } + +template // { dg-message "existing default declared here" } +struct A; + +template // { dg-message "existing default declared here" } +struct B; + +struct S { + template // { dg-message "existing default declared here" } + void x(); + + void y(int n = 456); // { dg-message "existing default declared here" } +}; + +struct nontrivial { nontrivial(int); }; +void h(nontrivial p = nontrivial(456)); // { dg-message "existing default declared here" "" { xfail *-*-* } } + +import "default-arg-2_a.H"; + +// { dg-error "conflicting default argument" "" { target *-*-* } 0 } diff --git a/gcc/testsuite/g++.dg/modules/default-arg-3.h b/gcc/testsuite/g++.dg/modules/default-arg-3.h new file mode 100644 index 00000000000..b55a6690f4a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-3.h @@ -0,0 +1,13 @@ +void f(int a, int b = 123); +template void g(T a, T b = 123); + +template struct A; +template struct B; + +struct S { + template void x(); + void y(int n = 123); +}; + +struct nontrivial { nontrivial(int); }; +void h(nontrivial p = nontrivial(123)); diff --git a/gcc/testsuite/g++.dg/modules/default-arg-3_a.H b/gcc/testsuite/g++.dg/modules/default-arg-3_a.H new file mode 100644 index 00000000000..879bedce67f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-3_a.H @@ -0,0 +1,5 @@ +// PR c++/99274 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#include "default-arg-3.h" diff --git a/gcc/testsuite/g++.dg/modules/default-arg-3_b.C b/gcc/testsuite/g++.dg/modules/default-arg-3_b.C new file mode 100644 index 00000000000..402dca6ff76 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/default-arg-3_b.C @@ -0,0 +1,6 @@ +// PR c++/99274 +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } +// Don't complain about matching defaults. + +#include "default-arg-3.h" +import "default-arg-3_a.H";