Skip to content

Conversation

@llvmbot
Copy link
Member

@llvmbot llvmbot commented Nov 6, 2025

Backport bc08e69

Requested by: @ChuanqiXu9

… 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)
@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
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

Status: Needs Merge

Development

Successfully merging this pull request may close these issues.

4 participants