[clang] 1a76d25 - [C++20][Modules][5/8] Diagnose wrong import/export for partition CMIs.
Iain Sandoe via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 26 03:27:24 PST 2022
Author: Iain Sandoe
Date: 2022-02-26T11:27:08Z
New Revision: 1a76d2563940e6b4bfcb9e77b8a4d1d3f0cc7d30
URL: https://github.com/llvm/llvm-project/commit/1a76d2563940e6b4bfcb9e77b8a4d1d3f0cc7d30
DIFF: https://github.com/llvm/llvm-project/commit/1a76d2563940e6b4bfcb9e77b8a4d1d3f0cc7d30.diff
LOG: [C++20][Modules][5/8] Diagnose wrong import/export for partition CMIs.
We cannot export partition implementation CMIs, but we can export the content
of partition interface CMIs.
Differential Revision: https://reviews.llvm.org/D118588
Added:
clang/test/Modules/cxx20-10-3-ex1.cpp
clang/test/Modules/cxx20-10-3-ex2.cpp
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaModule.cpp
clang/test/Modules/cxx20-import-diagnostics-a.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 15487260eb732..2528777678571 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10991,6 +10991,8 @@ def ext_module_import_not_at_top_level_noop : ExtWarn<
def note_module_import_not_at_top_level : Note<"%0 begins here">;
def err_module_self_import : Error<
"import of module '%0' appears within same top-level module '%1'">;
+def err_module_self_import_cxx20 : Error<
+ "import of module '%0' appears within its own %select{interface|implementation}1">;
def err_module_import_in_implementation : Error<
"@import of module '%0' in implementation of '%1'; use #import">;
@@ -11024,6 +11026,8 @@ def err_export_using_internal : Error<
def err_export_not_in_module_interface : Error<
"export declaration can only be used within a module interface unit"
"%select{ after the module declaration|}0">;
+def err_export_partition_impl : Error<
+ "module partition implementations cannot be exported">;
def err_export_in_private_module_fragment : Error<
"export declaration cannot be used in a private module fragment">;
def note_private_module_fragment : Note<
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index b2515075a7f23..0606b3a4edae8 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -403,10 +403,16 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
}
// Diagnose self-import before attempting a load.
+ // [module.import]/9
+ // A module implementation unit of a module M that is not a module partition
+ // shall not contain a module-import-declaration nominating M.
+ // (for an implementation, the module interface is imported implicitly,
+ // but that's handled in the module decl code).
+
if (getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
getCurrentModule()->Name == ModuleName) {
- Diag(ImportLoc, diag::err_module_self_import)
- << ModuleName << getLangOpts().CurrentModule;
+ Diag(ImportLoc, diag::err_module_self_import_cxx20)
+ << ModuleName << !ModuleScopes.back().ModuleInterface;
return true;
}
@@ -440,8 +446,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
// of the same top-level module. Until we do, make it an error rather than
// silently ignoring the import.
// FIXME: Should we warn on a redundant import of the current module?
- if (!getLangOpts().CPlusPlusModules &&
- Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
+ if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
(getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
Diag(ImportLoc, getLangOpts().isCompilingModule()
? diag::err_module_self_import
@@ -482,7 +487,12 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
if (!ModuleScopes.empty())
Context.addModuleInitializer(ModuleScopes.back().Module, Import);
- if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
+ // A module (partition) implementation unit shall not be exported.
+ if (getLangOpts().CPlusPlusModules && Mod && ExportLoc.isValid() &&
+ Mod->Kind == Module::ModuleKind::ModulePartitionImplementation) {
+ Diag(ExportLoc, diag::err_export_partition_impl)
+ << SourceRange(ExportLoc, Path.back().second);
+ } else if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
// Re-export the module if the imported module is exported.
// Note that we don't need to add re-exported module to Imports field
// since `Exports` implies the module is imported already.
@@ -494,7 +504,9 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
// [module.interface]p1:
// An export-declaration shall inhabit a namespace scope and appear in the
// purview of a module interface unit.
- Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
+ Diag(ExportLoc, diag::err_export_not_in_module_interface)
+ << (!ModuleScopes.empty() &&
+ !ModuleScopes.back().ImplicitGlobalModuleFragment);
} else if (getLangOpts().isCompilingModule()) {
Module *ThisModule = PP.getHeaderSearchInfo().lookupModule(
getLangOpts().CurrentModule, ExportLoc, false, false);
diff --git a/clang/test/Modules/cxx20-10-3-ex1.cpp b/clang/test/Modules/cxx20-10-3-ex1.cpp
new file mode 100644
index 0000000000000..69a48c4f7a4aa
--- /dev/null
+++ b/clang/test/Modules/cxx20-10-3-ex1.cpp
@@ -0,0 +1,36 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex1-tu1.cpp \
+// RUN: -o %t/M_PartImpl.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex1-tu2.cpp \
+// RUN: -fmodule-file=%t/M_PartImpl.pcm -o %t/M.pcm -verify
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex1-tu3.cpp \
+// RUN: -o %t/M_Part.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex1-tu4.cpp \
+// RUN: -fmodule-file=%t/M_Part.pcm -o %t/M.pcm
+
+//--- std10-3-ex1-tu1.cpp
+module M:PartImpl;
+
+// expected-no-diagnostics
+
+//--- std10-3-ex1-tu2.cpp
+export module M;
+ // error: exported partition :Part is an implementation unit
+export import :PartImpl; // expected-error {{module partition implementations cannot be exported}}
+
+//--- std10-3-ex1-tu3.cpp
+export module M:Part;
+
+// expected-no-diagnostics
+
+//--- std10-3-ex1-tu4.cpp
+export module M;
+export import :Part;
+
+// expected-no-diagnostics
diff --git a/clang/test/Modules/cxx20-10-3-ex2.cpp b/clang/test/Modules/cxx20-10-3-ex2.cpp
new file mode 100644
index 0000000000000..589d8cb7baa14
--- /dev/null
+++ b/clang/test/Modules/cxx20-10-3-ex2.cpp
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex2-tu1.cpp \
+// RUN: -o %t/M.pcm
+
+// RUN: %clang_cc1 -std=c++20 -S %t/std10-3-ex2-tu2.cpp \
+// RUN: -fmodule-file=%t/M.pcm -o %t/tu_8.s -verify
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std10-3-ex2-tu3.cpp \
+// RUN: -o %t/M.pcm -verify
+
+//--- std10-3-ex2-tu1.cpp
+export module M;
+
+//--- std10-3-ex2-tu2.cpp
+module M;
+ // error: cannot import M in its own unit
+import M; // expected-error {{import of module 'M' appears within its own implementation}}
+
+//--- std10-3-ex2-tu3.cpp
+export module M;
+ // error: cannot import M in its own unit
+import M; // expected-error {{import of module 'M' appears within its own interface}}
diff --git a/clang/test/Modules/cxx20-import-diagnostics-a.cpp b/clang/test/Modules/cxx20-import-diagnostics-a.cpp
index 8017e19e957d6..d940722f8ee8e 100644
--- a/clang/test/Modules/cxx20-import-diagnostics-a.cpp
+++ b/clang/test/Modules/cxx20-import-diagnostics-a.cpp
@@ -118,13 +118,13 @@ import B; // expected-error {{module imports cannot be in the private module fra
module B;
-import B; // expected-error {{import of module 'B' appears within same top-level module 'B'}}
+import B; // expected-error {{import of module 'B' appears within its own implementation}}
//--- import-diags-tu10.cpp
export module B;
-import B; // expected-error {{import of module 'B' appears within same top-level module 'B'}}
+import B; // expected-error {{import of module 'B' appears within its own interface}}
//--- import-diags-tu11.cpp
More information about the cfe-commits
mailing list