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
