[PATCH] D136953: [C++20] Diagnosed invalid and reserved module names
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 28 07:52:49 PDT 2022
aaron.ballman created this revision.
aaron.ballman added reviewers: iains, urnathan, ChuanqiXu, clang-language-wg.
Herald added a project: All.
aaron.ballman requested review of this revision.
Herald added a project: clang.
[module.unit]p1 specifies that `module` and `import` are invalid components of a module name, that module names cannot contain reserved identifiers, and that `std` followed by zero or more digits is reserved.
The first issue (`module` and `import` pseudo-keywords) requires a diagnostic, the second issue (use of reserved identifiers) does not require a diagnostic. We diagnose both the same -- the code is ill-formed unless the module declaration is in a system header. This allows STL implementations to use the reserved module names while preventing users from stealing them out from under us.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D136953
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaModule.cpp
clang/test/Modules/reserved-names.cpp
Index: clang/test/Modules/reserved-names.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/reserved-names.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// expected-note at 1 14{{add 'module;' to the start of the file to introduce a global module fragment}}
+
+module std; // expected-error {{'std' is a reserved name for a module}}
+module _Test; // expected-error {{'_Test' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+module module; // expected-error {{'module' is an invalid name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+module std0; // expected-error {{'std0' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+
+export module module; // expected-error {{'module' is an invalid name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module import; // expected-error {{'import' is an invalid name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module _Test; // expected-error {{'_Test' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module __test; // expected-error {{'__test' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module te__st; // expected-error {{'te__st' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module std; // expected-error {{'std' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module std0; // expected-error {{'std0' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module std1000000; // expected-error {{'std1000000' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+
+export module should_fail.std0; // expected-error {{'std0' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+export module should_fail._Test; // expected-error {{'_Test' is a reserved name for a module}} \
+ expected-error {{module declaration must occur at the start of the translation unit}}
+
+// Show that we suppress the diagnostic in a system header.
+# 100 "file.cpp" 1 3 // Enter a system header
+export module std; // expected-error {{module declaration must occur at the start of the translation unit}}
+# 100 "file.cpp" 2 3 // Leave the system header
Index: clang/lib/Sema/SemaModule.cpp
===================================================================
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -238,6 +238,33 @@
}
}
+ // C++2b [module.unit]p1: ... The identifiers module and import shall not
+ // appear as identifiers in a module-name or module-partition. All
+ // module-names either beginning with an identifier consisting of std
+ // followed by zero or more digits or containing a reserved identifier
+ // ([lex.name]) are reserved and shall not be specified in a
+ // module-declaration; no diagnostic is required.
+ for (auto Part : Path) {
+ int Reason = -1;
+ const IdentifierInfo *II = Part.first;
+ StringRef PartName = II->getName();
+ if (II->isStr("module") || II->isStr("import"))
+ Reason = /*invalid*/ 0;
+ else if (II->isReserved(getLangOpts()) !=
+ ReservedIdentifierStatus::NotReserved)
+ Reason = /*reserved*/ 1;
+ else if (PartName.startswith("std") &&
+ (PartName.size() == 3 || isDigit(PartName.drop_front(3)[0])))
+ Reason = /*reserved*/ 1;
+
+ // If the identifier is reserved but is in a system header, we do not
+ // diagnose (because we expect system headers to use reserved identifiers).
+ if (Reason != -1 && !getSourceManager().isInSystemHeader(Part.second)) {
+ Diag(Part.second, diag::err_invalid_module_name) << Part.first << Reason;
+ return nullptr;
+ }
+ }
+
// Flatten the dots in a module name. Unlike Clang's hierarchical module map
// modules, the dots here are just another character that can appear in a
// module name.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11205,6 +11205,8 @@
"private module fragment in module implementation unit">;
def note_not_module_interface_add_export : Note<
"add 'export' here if this is intended to be a module interface unit">;
+def err_invalid_module_name : Error<
+ "%0 is %select{an invalid|a reserved}1 name for a module">;
def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
"ambiguous use of internal linkage declaration %0 defined in multiple modules">,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136953.471550.patch
Type: text/x-patch
Size: 5640 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20221028/891e81c3/attachment-0001.bin>
More information about the cfe-commits
mailing list