Skip to content

Commit be66c50

Browse files
authored
[C++20] [Modules] Emit Errors when compiling a non-module source as module (#102565)
Close #101398 The root cause of the issue is that I removed the codes before and failed to recognize it in time and this was not found for a long time due to it only crashes with invalid codes.
1 parent 5297b75 commit be66c50

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11693,6 +11693,8 @@ def err_module_not_defined : Error<
1169311693
def err_module_redeclaration : Error<
1169411694
"translation unit contains multiple module declarations">;
1169511695
def note_prev_module_declaration : Note<"previous module declaration is here">;
11696+
def err_module_declaration_missing : Error<
11697+
"missing 'export module' declaration in module interface unit">;
1169611698
def err_module_declaration_missing_after_global_module_introducer : Error<
1169711699
"missing 'module' declaration at end of global module fragment "
1169811700
"introduced here">;

clang/lib/Sema/Sema.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,18 @@ void Sema::ActOnEndOfTranslationUnit() {
12721272
Module::ExplicitGlobalModuleFragment) {
12731273
Diag(ModuleScopes.back().BeginLoc,
12741274
diag::err_module_declaration_missing_after_global_module_introducer);
1275+
} else if (getLangOpts().getCompilingModule() ==
1276+
LangOptions::CMK_ModuleInterface &&
1277+
// We can't use ModuleScopes here since ModuleScopes is always
1278+
// empty if we're compiling the BMI.
1279+
!getASTContext().getCurrentNamedModule()) {
1280+
// If we are building a module interface unit, we should have seen the
1281+
// module declaration.
1282+
//
1283+
// FIXME: Make a better guess as to where to put the module declaration.
1284+
Diag(getSourceManager().getLocForStartOfFile(
1285+
getSourceManager().getMainFileID()),
1286+
diag::err_module_declaration_missing);
12751287
}
12761288

12771289
// Now we can decide whether the modules we're building need an initializer.

clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++20 %s -verify -o /dev/null
1+
// RUN: %clang_cc1 -std=c++20 %s -verify -emit-module-interface -o /dev/null
22
// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -verify -emit-module-interface -o %t
33
// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -verify -fmodule-file=A=%t -o /dev/null
44
//
@@ -15,6 +15,8 @@ module A; // #module-decl
1515
// expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
1616
#define INTERFACE
1717
#endif
18+
#else // Not in a module
19+
// expected-error@* {{missing 'export module' declaration in module interface unit}}
1820
#endif
1921

2022
#ifndef INTERFACE

clang/test/Modules/pr101398.cppm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %clang -std=c++20 -xc++-module %s -Xclang -verify --precompile -o %t/tmp.pcm
3+
// not modules
4+
5+
// expected-error@* {{missing 'export module' declaration in module interface unit}}

0 commit comments

Comments
 (0)