Skip to content

Conversation

@llvmbot
Copy link
Member

@llvmbot llvmbot commented Nov 6, 2025

Backport bc08e69

Requested by: @ChuanqiXu9

@llvmbot
Copy link
Member Author

llvmbot commented Nov 6, 2025

@ChuanqiXu9 What do you think about merging this PR to the release branch?

@llvmbot llvmbot requested a review from ChuanqiXu9 November 6, 2025 05:33
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:modules C++20 modules and Clang Header Modules labels Nov 6, 2025
@llvmbot
Copy link
Member Author

llvmbot commented Nov 6, 2025

@llvm/pr-subscribers-clang-modules

Author: None (llvmbot)

Changes

Backport bc08e69

Requested by: @ChuanqiXu9


Full diff: https://github.com/llvm/llvm-project/pull/166701.diff

2 Files Affected:

  • (modified) clang/lib/Serialization/ASTWriter.cpp (+1-2)
  • (added) clang/test/Modules/crash-enum-visibility-with-header-unit.cppm (+46)
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1a20fc9595dce..3caf9ebb32185 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4340,8 +4340,7 @@ class ASTDeclContextNameLookupTrait
     // parent of parent. We DON'T remove the enum constant from its parent. So
     // we don't need to care about merging problems here.
     if (auto *ECD = dyn_cast<EnumConstantDecl>(D);
-        ECD && DC.isFileContext() && ECD->getOwningModule() &&
-        ECD->getTopLevelOwningNamedModule()->isNamedModule()) {
+        ECD && DC.isFileContext() && ECD->getTopLevelOwningNamedModule()) {
       if (llvm::all_of(
               DC.noload_lookup(
                   cast<EnumDecl>(ECD->getDeclContext())->getDeclName()),
diff --git a/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm b/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm
new file mode 100644
index 0000000000000..90c57796dcf7e
--- /dev/null
+++ b/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm
@@ -0,0 +1,46 @@
+// Fixes #165445
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -x c++-user-header %t/header.h \
+// RUN:   -emit-header-unit -o %t/header.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -fmodule-file=%t/header.pcm \
+// RUN:   -emit-module-interface -o %t/A.pcm
+// 
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -fmodule-file=%t/header.pcm \
+// RUN:   -emit-module-interface -o %t/B.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp \
+// RUN:   -fmodule-file=A=%t/A.pcm -fmodule-file=B=%t/B.pcm  \
+// RUN:   -fmodule-file=%t/header.pcm \
+// RUN:   -verify -fsyntax-only
+
+//--- enum.h
+enum E { Value };
+
+//--- header.h
+#include "enum.h"
+
+//--- A.cppm
+module;
+#include "enum.h"
+export module A;
+
+auto e = Value;
+
+//--- B.cppm
+export module B;
+import "header.h";
+
+auto e = Value;
+
+//--- use.cpp
+// expected-no-diagnostics
+import A;
+import B;
+#include "enum.h"
+
+auto e = Value;

@llvmbot
Copy link
Member Author

llvmbot commented Nov 6, 2025

@llvm/pr-subscribers-clang

Author: None (llvmbot)

Changes

Backport bc08e69

Requested by: @ChuanqiXu9


Full diff: https://github.com/llvm/llvm-project/pull/166701.diff

2 Files Affected:

  • (modified) clang/lib/Serialization/ASTWriter.cpp (+1-2)
  • (added) clang/test/Modules/crash-enum-visibility-with-header-unit.cppm (+46)
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1a20fc9595dce..3caf9ebb32185 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4340,8 +4340,7 @@ class ASTDeclContextNameLookupTrait
     // parent of parent. We DON'T remove the enum constant from its parent. So
     // we don't need to care about merging problems here.
     if (auto *ECD = dyn_cast<EnumConstantDecl>(D);
-        ECD && DC.isFileContext() && ECD->getOwningModule() &&
-        ECD->getTopLevelOwningNamedModule()->isNamedModule()) {
+        ECD && DC.isFileContext() && ECD->getTopLevelOwningNamedModule()) {
       if (llvm::all_of(
               DC.noload_lookup(
                   cast<EnumDecl>(ECD->getDeclContext())->getDeclName()),
diff --git a/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm b/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm
new file mode 100644
index 0000000000000..90c57796dcf7e
--- /dev/null
+++ b/clang/test/Modules/crash-enum-visibility-with-header-unit.cppm
@@ -0,0 +1,46 @@
+// Fixes #165445
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -x c++-user-header %t/header.h \
+// RUN:   -emit-header-unit -o %t/header.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -fmodule-file=%t/header.pcm \
+// RUN:   -emit-module-interface -o %t/A.pcm
+// 
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -fmodule-file=%t/header.pcm \
+// RUN:   -emit-module-interface -o %t/B.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp \
+// RUN:   -fmodule-file=A=%t/A.pcm -fmodule-file=B=%t/B.pcm  \
+// RUN:   -fmodule-file=%t/header.pcm \
+// RUN:   -verify -fsyntax-only
+
+//--- enum.h
+enum E { Value };
+
+//--- header.h
+#include "enum.h"
+
+//--- A.cppm
+module;
+#include "enum.h"
+export module A;
+
+auto e = Value;
+
+//--- B.cppm
+export module B;
+import "header.h";
+
+auto e = Value;
+
+//--- use.cpp
+// expected-no-diagnostics
+import A;
+import B;
+#include "enum.h"
+
+auto e = Value;

@ChuanqiXu9
Copy link
Member

@ChuanqiXu9 What do you think about merging this PR to the release branch?

This is a simple fix. I think there is no risks.

@dyung dyung moved this from Needs Triage to Needs Review in LLVM Release Status Nov 7, 2025
@dyung
Copy link
Collaborator

dyung commented Nov 7, 2025

@ChuanqiXu9 What do you think about merging this PR to the release branch?

This is a simple fix. I think there is no risks.

Could you approve the port request as a formality if it is okay with you?

@ChuanqiXu9
Copy link
Member

@ChuanqiXu9 What do you think about merging this PR to the release branch?

This is a simple fix. I think there is no risks.

Could you approve the port request as a formality if it is okay with you?

Done

@dyung dyung moved this from Needs Review to Needs Merge in LLVM Release Status Nov 7, 2025
… units (llvm#166272)

Fixes llvm#165445.

Fixes a crash when `ASTWriter::GenerateNameLookupTable` processes enum
constants from C++20 header units.

The special handling for enum constants, introduced in fccc6ee, doesn't
account for declarations whose owning module is a C++20 header unit. It
calls `isNamedModule()` on the result of
`getTopLevelOwningNamedModule()`, which returns null for header units,
causing a null pointer dereference.

(cherry picked from commit bc08e69)
@dyung dyung merged commit 2fde0df into llvm:release/21.x Nov 12, 2025
13 checks passed
@github-project-automation github-project-automation bot moved this from Needs Merge to Done in LLVM Release Status Nov 12, 2025
@github-actions
Copy link

@ChuanqiXu9 (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

Development

Successfully merging this pull request may close these issues.

4 participants