https://github.com/ChuanqiXu9 created 
https://github.com/llvm/llvm-project/pull/215241

Close https://github.com/llvm/llvm-project/issues/204633

>From 6e49c4f39bec90fc7c298216d12119a067bb20d8 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <[email protected]>
Date: Mon, 10 Aug 2026 18:48:18 +0800
Subject: [PATCH] [C++20] [Modules] Don't treat non-named-module as interface
 unit for implementation unit

Close https://github.com/llvm/llvm-project/issues/204633
---
 clang/lib/Sema/SemaModule.cpp    |  5 +++++
 clang/test/Modules/GH204633.cppm | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 clang/test/Modules/GH204633.cppm

diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 667f36ab737ed..42c67cf89ed88 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -424,6 +424,11 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, 
SourceLocation ModuleLoc,
                                              /*IsInclusionDirective=*/false);
     const_cast<LangOptions &>(getLangOpts()).CurrentModule = ModuleName;
 
+    // A Clang module or a header unit cannot serve as the primary module
+    // interface while recovering from an implementation unit declaration.
+    if (Interface && !Interface->isNamedModule())
+      return nullptr;
+
     if (!Interface) {
       Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
       // Create an empty module interface unit for error recovery.
diff --git a/clang/test/Modules/GH204633.cppm b/clang/test/Modules/GH204633.cppm
new file mode 100644
index 0000000000000..4bcd1200a5568
--- /dev/null
+++ b/clang/test/Modules/GH204633.cppm
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-pc-win32 -fsyntax-only -fmodules \
+// RUN:   -fimplicit-module-maps -fmodules-cache-path=%t \
+// RUN:   -fmodule-map-file=%t/original.cppm -verify %t/original.cppm
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fmodules -verify %t/inline.cppm
+
+// Use the same file as both the source input and the module map. The module 
map
+// parser accepts this as a Clang module definition, while the C++ parser
+// diagnoses it as a malformed module declaration.
+//--- original.cppm
+// expected-error@+2 {{unexpected preprocessing token '{' after module name}}
+// expected-error@+1 {{module directive must end with a ';'}}
+module M {}
+
+// Build the conflicting Clang module inline.
+//--- inline.cppm
+// expected-no-diagnostics
+#pragma clang module build Foo
+module Foo {}
+#pragma clang module endbuild
+
+module Foo;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to