Skip to content

Commit cc5185b

Browse files
committed
[C++20] [Modules] Check TULocal entity within exported entities
See the attached test for example.
1 parent b4a0d7e commit cc5185b

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

clang/lib/Sema/SemaModule.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,16 @@ bool ExposureChecker::isExposureCandidate(const NamedDecl *D) {
12821282
// (outside the private-module-fragment, if any) or
12831283
// module partition is an exposure, the program is ill-formed.
12841284
Module *M = D->getOwningModule();
1285-
if (!M || !M->isInterfaceOrPartition())
1285+
if (!M)
1286+
return false;
1287+
// If M is implicit global module, the declaration must be in the purview of
1288+
// a module unit.
1289+
if (M->isImplicitGlobalModule()) {
1290+
M = M->Parent;
1291+
assert(M && "Implicit global module must have a parent");
1292+
}
1293+
1294+
if (!M->isInterfaceOrPartition())
12861295
return false;
12871296

12881297
if (D->isImplicit())
@@ -1495,6 +1504,16 @@ bool ExposureChecker::checkExposure(const Stmt *S, bool Diag) {
14951504

14961505
void ExposureChecker::checkExposureInContext(const DeclContext *DC) {
14971506
for (auto *TopD : DC->noload_decls()) {
1507+
if (auto *Export = dyn_cast<ExportDecl>(TopD)) {
1508+
checkExposureInContext(Export);
1509+
continue;
1510+
}
1511+
1512+
if (auto *LinkageSpec = dyn_cast<LinkageSpecDecl>(TopD)) {
1513+
checkExposureInContext(LinkageSpec);
1514+
continue;
1515+
}
1516+
14981517
auto *TopND = dyn_cast<NamedDecl>(TopD);
14991518
if (!TopND)
15001519
continue;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 -std=c++23 %s -verify -fsyntax-only
2+
export module M;
3+
static int local;
4+
export inline int exposure1() { return local; } // expected-warning {{TU local entity 'local' is exposed}}
5+
6+
static int local2 = 43;
7+
export extern "C++" {
8+
inline int exposure2() { return local2; } // expected-warning {{TU local entity 'local2' is exposed}}
9+
}

0 commit comments

Comments
 (0)