Author: Chuanqi Xu
Date: 2025-11-21T13:57:41+08:00
New Revision: cc5185bd146bed96d0d9e23263a56b6965d8572f

URL: 
https://github.com/llvm/llvm-project/commit/cc5185bd146bed96d0d9e23263a56b6965d8572f
DIFF: 
https://github.com/llvm/llvm-project/commit/cc5185bd146bed96d0d9e23263a56b6965d8572f.diff

LOG: [C++20] [Modules] Check TULocal entity within exported entities

See the attached test for example.

Added: 
    clang/test/Modules/reference-tu-local-var.cppm

Modified: 
    clang/lib/Sema/SemaModule.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index a2aa3eaaa7f6d..cbe37cd47793b 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -1282,7 +1282,16 @@ bool ExposureChecker::isExposureCandidate(const 
NamedDecl *D) {
   //   (outside the private-module-fragment, if any) or
   //   module partition is an exposure, the program is ill-formed.
   Module *M = D->getOwningModule();
-  if (!M || !M->isInterfaceOrPartition())
+  if (!M)
+    return false;
+  // If M is implicit global module, the declaration must be in the purview of
+  // a module unit.
+  if (M->isImplicitGlobalModule()) {
+    M = M->Parent;
+    assert(M && "Implicit global module must have a parent");
+  }
+
+  if (!M->isInterfaceOrPartition())
     return false;
 
   if (D->isImplicit())
@@ -1495,6 +1504,16 @@ bool ExposureChecker::checkExposure(const Stmt *S, bool 
Diag) {
 
 void ExposureChecker::checkExposureInContext(const DeclContext *DC) {
   for (auto *TopD : DC->noload_decls()) {
+    if (auto *Export = dyn_cast<ExportDecl>(TopD)) {
+      checkExposureInContext(Export);
+      continue;
+    }
+
+    if (auto *LinkageSpec = dyn_cast<LinkageSpecDecl>(TopD)) {
+      checkExposureInContext(LinkageSpec);
+      continue;
+    }
+
     auto *TopND = dyn_cast<NamedDecl>(TopD);
     if (!TopND)
       continue;

diff  --git a/clang/test/Modules/reference-tu-local-var.cppm 
b/clang/test/Modules/reference-tu-local-var.cppm
new file mode 100644
index 0000000000000..74a74d6b2f650
--- /dev/null
+++ b/clang/test/Modules/reference-tu-local-var.cppm
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++23 %s -verify -fsyntax-only
+export module M;
+static int local;
+export inline int exposure1() { return local; } // expected-warning {{TU local 
entity 'local' is exposed}}
+
+static int local2 = 43;
+export extern "C++" {
+inline int exposure2() { return local2; } // expected-warning {{TU local 
entity 'local2' is exposed}}
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to