From patchwork Sat Feb 8 14:16:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 106161 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 4BE1D3857720 for ; Sat, 8 Feb 2025 14:17:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4BE1D3857720 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=bjaqjA12 X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id 776433858D38 for ; Sat, 8 Feb 2025 14:16:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 776433858D38 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 776433858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::634 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1739024167; cv=none; b=o61uwcsfdLb8BQcM4NhMGawiuXAZydtjiluaZSVBF4scy18k4lyO6lJEa8mVFBDhUCLEcO4Sf15StLSBH8A4hRgQwol47X1C0wrQ6BQWo8DDoxMAv2QsuuMLLB3kWc14YXhAs2ZcN5aYz5x+BTEzM1UMlGy+65piDF8rgMRoKbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1739024167; c=relaxed/simple; bh=m4ymJlhR2KugHP8wlLacaI1+y1crXcbMwW7cngxH23Q=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=JyHJyRLcdjlyBg62sSoMofym927kAxXSu5eEgTF8nzCI9v6z82Xydr7d3k+QUdr8/D4WNpxsJ+zbRtJelInxTNJTK/BbMeTTjEWguIKE39f6mZIx8Uh4p0wQJw1hyHAyMT5UZPeWBIyHe338yzV7yjrHfM7uT+Dqnm14OS5tkDg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 776433858D38 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-2166db59927so6656075ad.0 for ; Sat, 08 Feb 2025 06:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739024166; x=1739628966; 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=tfv65minkOkuug0ppmcCKhiMrkGX6EFfDtWlcliKTdQ=; b=bjaqjA12EeVOwXVHAoLJbGjc51JyoA1GZy3VWuM8ho/tNOdAXtQbG3wcx1egMydnxh BNxFU9AVWqGD9zOTSNLvILPmigNpn2UP7OLUTzafFucE68SXqvTa5r5LDq32ZR0bpUcf iLscZ4y701rYybew4rw4V2EH9tlDXVaSZ5uOP4ZSMkGFc7R6p9OpXPbsiRToOzhfkvNQ rkw3HIvHxpa/u96vjvuP0ps6wirJDFOrLLreXpb9ZcAmsMETNMfVyX85r3bZLSR8CvjE NGFWZxXonnCPCzG2BxN/pMnFUzkydCsCvkPd9rNPf6kOHo8BASaTCDY8qDWhuVxdit9O hf1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739024166; x=1739628966; 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=tfv65minkOkuug0ppmcCKhiMrkGX6EFfDtWlcliKTdQ=; b=wFZx4mib8JLWjMK5HLa6MoJozc/DOz2joKQ4CmBmllupk5wCnFWxw5fjO3mC0yVMbm mfO5N3PV9YGIpyecpRs0GH3WaO7GdB/9bj6Y/xwxh8UGCZGkFORprWqAoEv88ff9h3BZ Kbj76kHLU91uPrl1GKeI9F/klzEpTiFiZSbLJJyvl6/49Tx2XlLWwoyQsZON3HzuQe1j i+yoZsJh6l71BX0Ta89hIbkQVzmw4qbP2UGJ8NoQLCkAhi9eNNytD+zA2q8hW3D+XUD1 aDzDrAIaWUCXndzZUE1FxqGQPj6DfpKDQsQ7f0A7KIc2WYQIiN9ERQI+B81vMDtTpqkR Nj7g== X-Gm-Message-State: AOJu0Ywc1q07N5lxw4nke2nOY/XxHoUfENfMVUj3S509RgRzfz73Z5wz uGPF6gc11qeSXXmGgC2GWXKO9NrgwYxybi8hBkdjoiGuuhiUOONoqem37w== X-Gm-Gg: ASbGncuxhnPX5uzBkCVM66buDMTim1YDlIECmQ1vIypGB/du7LlfVRaCWuYRUsj+w+I 5AMliJgvollNU1FJoB3grRwVSTVjomvKqNnDDIq9+PODux/9YZCneX5RapCufekvEy4s9S56Hej x/vD14ym1fV61SI5Z/uOkL3b58lD8trCjbArxAueP6Rdi4cUzwxvSkHDokJ+BwCoXw3xAP59xb4 OaczWykHu3J9p5FoY+gfckwDg8Wk7KoO3KIpPmq4jcC0e4JWC/iZU/4M4a5/48Jdo8gtLx8HbgY Di9GONlOwIbXCCxwtJZm0n2xe6hZcOywR2x58/NckK9nGGqbLBTVvDO9 X-Google-Smtp-Source: AGHT+IHTDbbG6qumUTZJz0p3Qh7ZV7QnsxMP8J0OFIS9sJbrbZ9QMVfv2K1r5pfTYNZOxGJ9XrwL+Q== X-Received: by 2002:a17:902:cf4a:b0:215:8721:30b7 with SMTP id d9443c01a7336-21f4e70ccbcmr41052405ad.11.1739024166149; Sat, 08 Feb 2025 06:16:06 -0800 (PST) Received: from Thaum. (163-47-68-2.ipv4.originbroadband.com.au. [163.47.68.2]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21f3687b1bbsm47110035ad.165.2025.02.08.06.16.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Feb 2025 06:16:05 -0800 (PST) Message-ID: <67a76725.170a0220.198739.1706@mx.google.com> X-Google-Original-Message-ID: Date: Sun, 9 Feb 2025 01:16:00 +1100 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill Subject: [PATCH] c++/modules: Better handle no-linkage decls in unnamed namespaces [PR118799] MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.0 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 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~patchwork=sourceware.org@gcc.gnu.org Tested on x86_64-pc-linux-gnu, OK for trunk if full bootstrap + regtest passes? -- >8 -- There are two issues with no-linkage decls (e.g. explicit type aliases) in unnamed namespaces that this patch fixes. Firstly, we don't currently handle exporting no-linkage decls in unnamed namespaces. This should be ill-formed in [module.export], since having an exported declaration within a namespace-definition makes the namespace definition exported (p2), but an unnamed namespace has internal linkage thus violating p3. Secondly, by the standard it appears to be possible to emit unnamed namespaces from named modules in certain scenarios. This patch makes the adjustments needed to ensure we don't error in this case. PR c++/118799 gcc/cp/ChangeLog: * module.cc (depset::hash::is_tu_local_entity): Only types, functions, variables, and template (specialisations) can be TU-local. (module_state::write_namespaces): Allow unnamed namespaces in named modules. (check_module_decl_linkage): Error for all exported declarations in an unnamed namespace. gcc/testsuite/ChangeLog: * g++.dg/modules/export-6.C: Adjust error message, add check for no-linkage decls in namespace. * g++.dg/modules/internal-4_b.C: Allow exposing a namespace with internal linkage. * g++.dg/modules/using-30_a.C: New test. * g++.dg/modules/using-30_b.C: New test. * g++.dg/modules/using-30_c.C: New test. Signed-off-by: Nathaniel Shead Signed-off-by: Nathaniel Shead Signed-off-by: Nathaniel Shead --- gcc/cp/module.cc | 35 ++++++++++++++++----- gcc/testsuite/g++.dg/modules/export-6.C | 33 ++++++++++--------- gcc/testsuite/g++.dg/modules/internal-4_b.C | 4 +-- gcc/testsuite/g++.dg/modules/using-30_a.C | 9 ++++++ gcc/testsuite/g++.dg/modules/using-30_b.C | 6 ++++ gcc/testsuite/g++.dg/modules/using-30_c.C | 13 ++++++++ 6 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/using-30_a.C create mode 100644 gcc/testsuite/g++.dg/modules/using-30_b.C create mode 100644 gcc/testsuite/g++.dg/modules/using-30_c.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 59716e1873e..21251f98a35 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13332,6 +13332,14 @@ depset::hash::is_tu_local_entity (tree decl, bool explain/*=false*/) { gcc_checking_assert (DECL_P (decl)); + /* Only types, functions, variables, and template (specialisations) + can be TU-local. */ + if (TREE_CODE (decl) != TYPE_DECL + && TREE_CODE (decl) != FUNCTION_DECL + && TREE_CODE (decl) != VAR_DECL + && TREE_CODE (decl) != TEMPLATE_DECL) + return false; + /* An explicit type alias is not an entity, and so is never TU-local. Neither are the built-in declarations of 'int' and such. */ if (TREE_CODE (decl) == TYPE_DECL @@ -16433,8 +16441,9 @@ module_state::write_namespaces (elf_out *to, vec spaces, depset *b = spaces[ix]; tree ns = b->get_entity (); + /* This could be an anonymous namespace even for a named module, + since we can still emit no-linkage decls. */ gcc_checking_assert (TREE_CODE (ns) == NAMESPACE_DECL); - gcc_checking_assert (TREE_PUBLIC (ns) || header_module_p ()); unsigned flags = 0; if (TREE_PUBLIC (ns)) @@ -20394,13 +20403,25 @@ check_module_decl_linkage (tree decl) /* An internal-linkage declaration cannot be generally be exported. But it's OK to export any declaration from a header unit, including internal linkage declarations. */ - if (!header_module_p () - && DECL_MODULE_EXPORT_P (decl) - && decl_linkage (decl) == lk_internal) + if (!header_module_p () && DECL_MODULE_EXPORT_P (decl)) { - error_at (DECL_SOURCE_LOCATION (decl), - "exporting declaration %qD with internal linkage", decl); - DECL_MODULE_EXPORT_P (decl) = false; + /* Let's additionally treat any exported declaration within an + internal namespace as exporting a declaration with internal + linkage, as this would implicitly also export the internal + linkage namespace. */ + if (decl_internal_context_p (decl)) + { + error_at (DECL_SOURCE_LOCATION (decl), + "exporting declaration %qD declared in unnamed namespace", + decl); + DECL_MODULE_EXPORT_P (decl) = false; + } + else if (decl_linkage (decl) == lk_internal) + { + error_at (DECL_SOURCE_LOCATION (decl), + "exporting declaration %qD with internal linkage", decl); + DECL_MODULE_EXPORT_P (decl) = false; + } } } diff --git a/gcc/testsuite/g++.dg/modules/export-6.C b/gcc/testsuite/g++.dg/modules/export-6.C index 460cdf08ea9..af54e5fbe87 100644 --- a/gcc/testsuite/g++.dg/modules/export-6.C +++ b/gcc/testsuite/g++.dg/modules/export-6.C @@ -16,27 +16,32 @@ export static auto [d] = S{}; // { dg-error "internal linkage" "" { target c++2 #endif namespace { - export int y = 456; // { dg-error "internal linkage" } - export void h(); // { dg-error "internal linkage" } - export void i() {} // { dg-error "internal linkage" } - export template void v(); // { dg-error "internal linkage" } - export template void w() {} // { dg-error "internal linkage" } - export auto [e] = S{}; // { dg-error "internal linkage" } + export int y = 456; // { dg-error "exporting" } + export void h(); // { dg-error "exporting" } + export void i() {} // { dg-error "exporting" } + export template void v(); // { dg-error "exporting" } + export template void w() {} // { dg-error "exporting" } + export auto [e] = S{}; // { dg-error "exporting" } - export namespace ns {} // { dg-error "internal linkage" } - export namespace alias = global; // { dg-error "internal linkage" } + export namespace ns {} // { dg-error "exporting" } + export namespace alias = global; // { dg-error "exporting" } - export struct A {}; // { dg-error "internal linkage" } - export template struct B {}; // { dg-error "internal linkage" } + export struct A {}; // { dg-error "exporting" } + export template struct B {}; // { dg-error "exporting" } - export enum E {}; // { dg-error "internal linkage" } - export enum class F {}; // { dg-error "internal linkage" } + export enum E {}; // { dg-error "exporting" } + export enum class F {}; // { dg-error "exporting" } - export template using U = int; // { dg-error "internal linkage" } + export template using U = int; // { dg-error "exporting" } #if __cplusplus >= 202002L - export template concept C = true; // { dg-error "internal linkage" "" { target c++20 } } + export template concept C = true; // { dg-error "exporting" "" { target c++20 } } #endif + + // Also complain about exporting no-linkage decls in an unnamed namespace + export typedef int T; // { dg-error "exporting" } + export typedef struct {} *PC; // { dg-error "exporting" } + export using V = int; // { dg-error "exporting" } } export namespace {} // { dg-error "exporting unnamed namespace" } diff --git a/gcc/testsuite/g++.dg/modules/internal-4_b.C b/gcc/testsuite/g++.dg/modules/internal-4_b.C index 81fc65a69bd..7e4fbfeb1fb 100644 --- a/gcc/testsuite/g++.dg/modules/internal-4_b.C +++ b/gcc/testsuite/g++.dg/modules/internal-4_b.C @@ -32,8 +32,8 @@ inline void expose_header_decl() { // { dg-error "exposes TU-local entity" } header_f(); } -// We additionally consider a namespace with internal linkage as TU-local -namespace expose_ns = internal_ns; // { dg-error "exposes TU-local entity" } +// A namespace with internal linkage is not inherently an exposure. +namespace expose_ns = internal_ns; // { dg-bogus "exposes TU-local entity" } // But we don't consider a weakref as being TU-local, despite being // marked static; this is to support uses of weakrefs in header files diff --git a/gcc/testsuite/g++.dg/modules/using-30_a.C b/gcc/testsuite/g++.dg/modules/using-30_a.C new file mode 100644 index 00000000000..fc6a67f2bae --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-30_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M } + +export module M; + +namespace { + using A = int; + typedef int B; +} diff --git a/gcc/testsuite/g++.dg/modules/using-30_b.C b/gcc/testsuite/g++.dg/modules/using-30_b.C new file mode 100644 index 00000000000..ba06c9de792 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-30_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules" } + +module M; + +A x; +B y; diff --git a/gcc/testsuite/g++.dg/modules/using-30_c.C b/gcc/testsuite/g++.dg/modules/using-30_c.C new file mode 100644 index 00000000000..34dc6f2c98d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-30_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules" } +// The different declarations in the anonymous namespace shouldn't clash with +// those in M. + +namespace { + using A = double; + typedef double B; +} +import M; +int main() { + A a = 1.0; + B b = 2.0; +}