[clang] [clang] Fix #embed with C++20 modules (PR #197434)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 13 06:18:58 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Mariya Podchishchaeva (Fznamznon)
<details>
<summary>Changes</summary>
Fix a bug in EmbedExpr's constructor, correct serialization to make sure to initialize all required fields and add a test.
Fixes https://github.com/llvm/llvm-project/issues/195350
---
Full diff: https://github.com/llvm/llvm-project/pull/197434.diff
5 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/include/clang/AST/Expr.h (+1-1)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+8-2)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (-1)
- (added) clang/test/Modules/embed-directive.cppm (+28)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bd91b8723a5c6..991cd35239926 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -546,6 +546,7 @@ Bug Fixes in This Version
- Fixed a crash when parsing invalid ``static_assert`` declarations with string-literal messages (#GH187690).
- Fixed a potential stack-use-after-return issue in Clang when copy-initializing
an array via an element-at-a-time copy loop (#GH192026)
+- Fixed a crash when ``#embed`` is used with C++ modules (#GH195350)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 393fe275c6269..caaa10c1bf0ee 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -5137,7 +5137,7 @@ class EmbedExpr final : public Expr {
public:
EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data,
unsigned Begin, unsigned NumOfElements);
- explicit EmbedExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}
+ explicit EmbedExpr(EmptyShell Empty) : Expr(EmbedExprClass, Empty) {}
SourceLocation getLocation() const { return EmbedKeywordLoc; }
SourceLocation getBeginLoc() const { return EmbedKeywordLoc; }
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 4ada1dc58042d..903c52632cab3 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1388,8 +1388,14 @@ void ASTStmtReader::VisitEmbedExpr(EmbedExpr *E) {
EmbedDataStorage *Data = new (Record.getContext()) EmbedDataStorage;
Data->BinaryData = cast<StringLiteral>(Record.readSubStmt());
E->Data = Data;
- E->Begin = Record.readInt();
- E->NumOfElements = Record.readInt();
+ E->Begin = Record.readUInt32();
+ E->NumOfElements = Record.readUInt32();
+ ASTContext &Ctx = Record.getContext();
+ E->Ctx = &Ctx;
+ E->setType(Ctx.IntTy);
+ E->FakeChildNode = IntegerLiteral::Create(
+ Ctx, llvm::APInt::getZero(Ctx.getTypeSize(E->getType())), E->getType(),
+ E->EmbedKeywordLoc);
}
void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 47cbef06c3cc4..9130e88227519 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1339,7 +1339,6 @@ void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
void ASTStmtWriter::VisitEmbedExpr(EmbedExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getBeginLoc());
- Record.AddSourceLocation(E->getEndLoc());
Record.AddStmt(E->getDataStringLiteral());
Record.writeUInt32(E->getStartingElementPos());
Record.writeUInt32(E->getDataElementCount());
diff --git a/clang/test/Modules/embed-directive.cppm b/clang/test/Modules/embed-directive.cppm
new file mode 100644
index 0000000000000..1d2448c685870
--- /dev/null
+++ b/clang/test/Modules/embed-directive.cppm
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %t/foo.cppm -emit-module-interface \
+// RUN: -o %t/foo.pcm
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %t/user.cc -fmodule-file=foo=%t/foo.pcm \
+// RUN: -emit-llvm -o - -disable-llvm-passes | FileCheck %t/user.cc
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %t/user.cc -fmodule-file=foo=%t/foo.pcm \
+// RUN: -fexperimental-new-constant-interpreter -emit-llvm -o - -disable-llvm-passes | FileCheck %t/user.cc
+
+//--- foo.cppm
+// embed content
+
+export module foo;
+
+export constexpr const char data[] = {
+#embed __FILE__ limit(16)
+ , 0};
+
+//--- user.cc
+export module importer;
+import foo;
+
+constexpr auto d = data;
+static_assert(d[0] == '/');
+
+// CHECK: @{{.*}}data{{.*}} = {{.*}} constant [17 x i8] c"// embed content\00", align 16
``````````
</details>
https://github.com/llvm/llvm-project/pull/197434
More information about the cfe-commits
mailing list