-
Notifications
You must be signed in to change notification settings - Fork 15.1k
release/21.x: [clang][modules] Fix crash in enum visibility lookup for C++20 header units (#166272) #166701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/21.x
Are you sure you want to change the base?
Conversation
… 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)
|
@ChuanqiXu9 What do you think about merging this PR to the release branch? |
|
@llvm/pr-subscribers-clang-modules Author: None (llvmbot) ChangesBackport bc08e69 Requested by: @ChuanqiXu9 Full diff: https://github.com/llvm/llvm-project/pull/166701.diff 2 Files Affected:
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;
|
|
@llvm/pr-subscribers-clang Author: None (llvmbot) ChangesBackport bc08e69 Requested by: @ChuanqiXu9 Full diff: https://github.com/llvm/llvm-project/pull/166701.diff 2 Files Affected:
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;
|
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 |
Backport bc08e69
Requested by: @ChuanqiXu9