summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-11-21 13:55:32 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-11-21 13:57:41 +0800
commitcc5185bd146bed96d0d9e23263a56b6965d8572f (patch)
treec0af8c0ceef95295c8cad80a26591fc504864796 /clang
parentb4a0d7e89fac280b2917b3fca906ad2f3a52da74 (diff)
[C++20] [Modules] Check TULocal entity within exported entities
See the attached test for example.
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaModule.cpp21
-rw-r--r--clang/test/Modules/reference-tu-local-var.cppm9
2 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index a2aa3eaaa7f6..cbe37cd47793 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 000000000000..74a74d6b2f65
--- /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}}
+}