[clang] [clang][Modules] Reject export declarations in implementation partitions (PR #188698)

Victor Chernyakin via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 26 00:28:13 PDT 2026


https://github.com/localspook created https://github.com/llvm/llvm-project/pull/188698

None

>From f14b03f938bbcd3cc51f66e2f4022ed236a06e89 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victor.j at outlook.com>
Date: Thu, 26 Mar 2026 00:26:04 -0700
Subject: [PATCH] [clang][Modules] Reject export declarations in implementation
 partitions

---
 clang/docs/ReleaseNotes.rst                   |  3 +++
 clang/include/clang/Sema/Sema.h               |  7 ++++---
 clang/test/CXX/module/module.interface/p1.cpp | 18 ++++++++++++++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b92f1ab34aa51..3a27c41cb3e31 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -46,6 +46,9 @@ C++ Specific Potentially Breaking Changes
 - Clang now more aggressively optimizes away stores to objects after they are
   dead. This behavior can be disabled with ``-fno-lifetime-dse``.
 
+- Clang now correctly rejects ``export`` directives in module implementation
+  partitions. (#GH107602)
+
 ABI Changes in This Version
 ---------------------------
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 832e46286194a..5dfac33d6ef0d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9914,9 +9914,10 @@ class Sema final : public SemaBase {
 
   /// Is the module scope we are an implementation unit?
   bool currentModuleIsImplementation() const {
-    return ModuleScopes.empty()
-               ? false
-               : ModuleScopes.back().Module->isModuleImplementation();
+    if (ModuleScopes.empty())
+      return false;
+    const Module *M = ModuleScopes.back().Module;
+    return M->isModuleImplementation() || M->isModulePartitionImplementation();
   }
 
   // When loading a non-modular PCH files, this is used to restore module
diff --git a/clang/test/CXX/module/module.interface/p1.cpp b/clang/test/CXX/module/module.interface/p1.cpp
index 1754d9ea14618..d3e4f756452db 100644
--- a/clang/test/CXX/module/module.interface/p1.cpp
+++ b/clang/test/CXX/module/module.interface/p1.cpp
@@ -4,6 +4,8 @@
 // RUN: %clang_cc1 -std=c++2a %t/errors.cpp -verify
 // RUN: %clang_cc1 -std=c++2a %t/M.cppm -emit-module-interface -o %t/M.pcm
 // RUN: %clang_cc1 -std=c++2a %t/impl.cpp -fmodule-file=M=%t/M.pcm -verify
+// RUN: %clang_cc1 -std=c++2a %t/interface-partition.cppm -emit-module-interface -o %t/L-P1.pcm
+// RUN: %clang_cc1 -std=c++2a %t/implementation-partition.cpp -fmodule-file=L:P1=%t/L-P1.pcm -verify
 
 //--- errors.cpp
 module;
@@ -42,3 +44,19 @@ namespace N {
   export int c2; // expected-error {{export declaration can only be used within a module interface}}
 }
 // expected-note@#M 2+{{add 'export'}}
+
+//--- interface-partition.cppm
+
+export module L:P1;
+
+//--- implementation-partition.cpp
+
+module L:P2; // #M
+
+export import :P1; // expected-error {{export declaration can only be used within a module interface}}
+
+export int b3; // expected-error {{export declaration can only be used within a module interface}}
+namespace N {
+  export int c3; // expected-error {{export declaration can only be used within a module interface}}
+}
+// expected-note@#M 2+{{add 'export'}}



More information about the cfe-commits mailing list