https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/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 >From f5e5d21ff6d2b4b4dc36f3d07046fd0a14c6016a Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <[email protected]> Date: Wed, 13 May 2026 06:07:05 -0700 Subject: [PATCH] [clang] Fix #embed with C++20 modules 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 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/Expr.h | 2 +- clang/lib/Serialization/ASTReaderStmt.cpp | 10 ++++++-- clang/lib/Serialization/ASTWriterStmt.cpp | 1 - clang/test/Modules/embed-directive.cppm | 28 +++++++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 clang/test/Modules/embed-directive.cppm 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
