Author: Mariya Podchishchaeva
Date: 2026-05-18T11:37:35Z
New Revision: 858f734d2d2ae74306e12ee726cc51e098c687d4

URL: 
https://github.com/llvm/llvm-project/commit/858f734d2d2ae74306e12ee726cc51e098c687d4
DIFF: 
https://github.com/llvm/llvm-project/commit/858f734d2d2ae74306e12ee726cc51e098c687d4.diff

LOG: [clang] Fix #embed with C++20 modules (#197434)

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

Added: 
    clang/test/Modules/embed-directive.cppm

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/Expr.h
    clang/lib/Serialization/ASTReaderStmt.cpp
    clang/lib/Serialization/ASTWriterStmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b0c2179a3aec1..3aea1c28c3cae 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -562,6 +562,7 @@ Bug Fixes in This Version
 - 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 an issue where certain designated initializers would be rejected for 
constexpr variables. (#GH193373)
+- 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 885c8ceea71c1..b91bf4a5375fb 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 39a37c6dacb2a..7e51ce8c0aca2 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1389,8 +1389,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 e1613b777b95a..a7e815a1ef438 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1340,7 +1340,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


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

Reply via email to