Skip to content

Commit 82034ac

Browse files
authored
[C++20] [Modules] Warn for importing implementation partition unit in interface units (#108493)
Recently, there are multiple false positive issue reports about the reachability of implementation partition units: - #105882 - #101348 - https://lists.isocpp.org/core/2024/08/16232.php And according to our use experience for modules, we find it is a pretty good practice to not import implementation partition units in the interface units. It can help developers to have a pretty good mental model for when to use an implementation partition unit: that any unit in the module but not in the module interfaces can be in the implementation partition unit. So I think it is good to add the diagnostics.
1 parent 390b82d commit 82034ac

File tree

5 files changed

+16
-2
lines changed

5 files changed

+16
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ Improvements to Clang's diagnostics
303303

304304
- Clang now warns for u8 character literals used in C23 with ``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``.
305305

306+
- Clang now diagnose when importing module implementation partition units in module interface units.
307+
306308
Improvements to Clang's time-trace
307309
----------------------------------
308310

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ def warn_deprecated_literal_operator_id: Warning<
442442
"is deprecated">, InGroup<DeprecatedLiteralOperator>, DefaultIgnore;
443443
def warn_reserved_module_name : Warning<
444444
"%0 is a reserved name for a module">, InGroup<ReservedModuleIdentifier>;
445+
def warn_import_implementation_partition_unit_in_interface_unit : Warning<
446+
"importing an implementation partition unit in a module interface is not recommended. "
447+
"Names from %0 may not be reachable">,
448+
InGroup<DiagGroup<"import-implementation-partition-unit-in-interface-unit">>;
445449

446450
def warn_parameter_size: Warning<
447451
"%0 is a large (%1 bytes) pass-by-value argument; "

clang/lib/Sema/SemaModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,14 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
650650
else
651651
VisibleModules.setVisible(Mod, ImportLoc);
652652

653+
assert((!Mod->isModulePartitionImplementation() || getCurrentModule()) &&
654+
"We can only import a partition unit in a named module.");
655+
if (Mod->isModulePartitionImplementation() &&
656+
getCurrentModule()->isModuleInterfaceUnit())
657+
Diag(ImportLoc,
658+
diag::warn_import_implementation_partition_unit_in_interface_unit)
659+
<< Mod->Name;
660+
653661
checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
654662

655663
// FIXME: we should support importing a submodule within a different submodule

clang/test/CXX/module/module.import/p2.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ void test() {
3030
}
3131

3232
//--- UseInPartA.cppm
33-
// expected-no-diagnostics
3433
export module M:partA;
35-
import :impl;
34+
import :impl; // expected-warning {{importing an implementation partition unit in a module interface is not recommended.}}
3635
void test() {
3736
A a;
3837
}

clang/test/Modules/cxx20-10-3-ex1.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module M:PartImpl;
3737
export module M;
3838
// error: exported partition :Part is an implementation unit
3939
export import :PartImpl; // expected-error {{module partition implementations cannot be exported}}
40+
// expected-warning@-1 {{importing an implementation partition unit in a module interface is not recommended.}}
4041

4142
//--- std10-3-ex1-tu3.cpp
4243
export module M:Part;

0 commit comments

Comments
 (0)