[llvm-branch-commits] [llvm] 7113de3 - [ScalarizeMaskedMemIntrin] Add missing dependency
Author: Mariya Podchishchaeva Date: 2021-01-19T22:33:47+03:00 New Revision: 7113de301a846521a2bdd73d44ac9cf5827b37a6 URL: https://github.com/llvm/llvm-project/commit/7113de301a846521a2bdd73d44ac9cf5827b37a6 DIFF: https://github.com/llvm/llvm-project/commit/7113de301a846521a2bdd73d44ac9cf5827b37a6.diff LOG: [ScalarizeMaskedMemIntrin] Add missing dependency The pass has dependency on 'TargetTransformInfoWrapperPass', but the corresponding call to INITIALIZE_PASS_DEPENDENCY was missing. Differential Revision: https://reviews.llvm.org/D94916 Added: Modified: llvm/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp Removed: diff --git a/llvm/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp b/llvm/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp index 725e15f8b06e..afa2d1bc7966 100644 --- a/llvm/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp @@ -72,8 +72,13 @@ static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, char ScalarizeMaskedMemIntrinLegacyPass::ID = 0; -INITIALIZE_PASS(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE, -"Scalarize unsupported masked memory intrinsics", false, false) +INITIALIZE_PASS_BEGIN(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE, + "Scalarize unsupported masked memory intrinsics", false, + false) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE, +"Scalarize unsupported masked memory intrinsics", false, +false) FunctionPass *llvm::createScalarizeMaskedMemIntrinLegacyPass() { return new ScalarizeMaskedMemIntrinLegacyPass(); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Reject if constexpr in C (#112685) (PR #112697)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/112697 Fixes https://github.com/llvm/llvm-project/issues/112587 >From 35dd9fa1ca01c0c7204a4d8677c615c0956fd397 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Thu, 17 Oct 2024 13:42:35 +0200 Subject: [PATCH] [clang] Reject if constexpr in C (#112685) Fixes https://github.com/llvm/llvm-project/issues/112587 --- clang/lib/Parse/ParseStmt.cpp | 11 +++ clang/test/Sema/constexpr.c | 7 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 22d38adc28ebe9..3ac1f0fa27f83f 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1508,10 +1508,13 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { SourceLocation ConstevalLoc; if (Tok.is(tok::kw_constexpr)) { -Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if -: diag::ext_constexpr_if); -IsConstexpr = true; -ConsumeToken(); +// C23 supports constexpr keyword, but only for object definitions. +if (getLangOpts().CPlusPlus) { + Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if + : diag::ext_constexpr_if); + IsConstexpr = true; + ConsumeToken(); +} } else { if (Tok.is(tok::exclaim)) { NotLocation = ConsumeToken(); diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c index 8286cd2107d2f2..a874fd64808404 100644 --- a/clang/test/Sema/constexpr.c +++ b/clang/test/Sema/constexpr.c @@ -357,3 +357,10 @@ void infsNaNs() { constexpr double db5 = LD_SNAN; // expected-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}} constexpr double db6 = INF; } + +void constexprif() { + if constexpr (300) {} //expected-error {{expected '(' after 'if'}} +} +void constevalif() { + if consteval (300) {} //expected-error {{expected '(' after 'if'}} +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Reject if constexpr in C (#112685) (PR #112697)
https://github.com/Fznamznon milestoned https://github.com/llvm/llvm-project/pull/112697 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix C23 constexpr crashes (#112708) (PR #112855)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/112855 Before using a constexpr variable that is not properly initialized check that it is valid. Fixes https://github.com/llvm/llvm-project/issues/109095 Fixes https://github.com/llvm/llvm-project/issues/112516 >From d3121f27d84c2b254d6ba551be45ce020cfa5a10 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Fri, 18 Oct 2024 10:18:34 +0200 Subject: [PATCH] [clang] Fix C23 constexpr crashes (#112708) Before using a constexpr variable that is not properly initialized check that it is valid. Fixes https://github.com/llvm/llvm-project/issues/109095 Fixes https://github.com/llvm/llvm-project/issues/112516 --- clang/lib/AST/Decl.cpp | 10 +++--- clang/test/Sema/constexpr.c | 14 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 490c4a2fc525cd..bc7cce0bcd7fc2 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2503,7 +2503,8 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const { if (!DefVD->mightBeUsableInConstantExpressions(Context)) return false; // ... and its initializer is a constant initializer. - if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization()) + if ((Context.getLangOpts().CPlusPlus || getLangOpts().C23) && + !DefVD->hasConstantInitialization()) return false; // C++98 [expr.const]p1: // An integral constant-expression can involve only [...] const variables @@ -2610,8 +2611,11 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const { } bool VarDecl::hasConstantInitialization() const { - // In C, all globals (and only globals) have constant initialization. - if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus) + // In C, all globals and constexpr variables should have constant + // initialization. For constexpr variables in C check that initializer is a + // constant initializer because they can be used in constant expressions. + if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus && + !isConstexpr()) return true; // In C++, it depends on whether the evaluation at the point of definition diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c index 8286cd2107d2f2..0bf3a41c18d76d 100644 --- a/clang/test/Sema/constexpr.c +++ b/clang/test/Sema/constexpr.c @@ -357,3 +357,17 @@ void infsNaNs() { constexpr double db5 = LD_SNAN; // expected-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}} constexpr double db6 = INF; } + +void ghissue112516() { + struct S11 *s11 = 0; + constexpr int num = s11->len; // expected-error {{constexpr variable 'num' must be initialized by a constant expression}} + void *Arr[num]; +} + +void ghissue109095() { + constexpr char c[] = { 'a' }; + constexpr int i = c[1]; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}}\ + // expected-note {{declared here}} + _Static_assert(i == c[0]); // expected-error {{static assertion expression is not an integral constant expression}}\ + // expected-note {{initializer of 'i' is not a constant expression}} +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix C23 constexpr crashes (#112708) (PR #112855)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/112855 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix C23 constexpr crashes (#112708) (PR #112855)
https://github.com/Fznamznon milestoned https://github.com/llvm/llvm-project/pull/112855 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix C23 constexpr crashes (#112708) (PR #112855)
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/112855 >From fb40fba6f9caf44a1e839525efdaebdf936c2934 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Fri, 18 Oct 2024 10:18:34 +0200 Subject: [PATCH] [clang] Fix C23 constexpr crashes (#112708) Before using a constexpr variable that is not properly initialized check that it is valid. Fixes https://github.com/llvm/llvm-project/issues/109095 Fixes https://github.com/llvm/llvm-project/issues/112516 --- clang/lib/AST/Decl.cpp | 10 +++--- clang/test/Sema/constexpr.c | 17 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 490c4a2fc525cd..bc7cce0bcd7fc2 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2503,7 +2503,8 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const { if (!DefVD->mightBeUsableInConstantExpressions(Context)) return false; // ... and its initializer is a constant initializer. - if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization()) + if ((Context.getLangOpts().CPlusPlus || getLangOpts().C23) && + !DefVD->hasConstantInitialization()) return false; // C++98 [expr.const]p1: // An integral constant-expression can involve only [...] const variables @@ -2610,8 +2611,11 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const { } bool VarDecl::hasConstantInitialization() const { - // In C, all globals (and only globals) have constant initialization. - if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus) + // In C, all globals and constexpr variables should have constant + // initialization. For constexpr variables in C check that initializer is a + // constant initializer because they can be used in constant expressions. + if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus && + !isConstexpr()) return true; // In C++, it depends on whether the evaluation at the point of definition diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c index 8286cd2107d2f2..fe014fadb11ec8 100644 --- a/clang/test/Sema/constexpr.c +++ b/clang/test/Sema/constexpr.c @@ -357,3 +357,20 @@ void infsNaNs() { constexpr double db5 = LD_SNAN; // expected-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}} constexpr double db6 = INF; } + +struct S11 { + int len; +}; +void ghissue112516() { + struct S11 *s11 = 0; + constexpr int num = s11->len; // expected-error {{constexpr variable 'num' must be initialized by a constant expression}} + void *Arr[num]; +} + +void ghissue109095() { + constexpr char c[] = { 'a' }; + constexpr int i = c[1]; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}}\ + // expected-note {{declared here}} + _Static_assert(i == c[0]); // expected-error {{static assertion expression is not an integral constant expression}}\ + // expected-note {{initializer of 'i' is not a constant expression}} +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [Coverage] Make additional counters available for BranchRegion. NFC. (PR #120930)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/120930 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix preprocessor output from #embed (#126742) (PR #127222)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/127222 When bytes with negative signed char values appear in the data, make sure to use raw bytes from the data string when preprocessing, not char values. Fixes https://github.com/llvm/llvm-project/issues/102798 >From 95cf7310c15324f25e9e5276772278fa58ba6926 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Thu, 13 Feb 2025 10:59:21 +0100 Subject: [PATCH] [clang] Fix preprocessor output from #embed (#126742) When bytes with negative signed char values appear in the data, make sure to use raw bytes from the data string when preprocessing, not char values. Fixes https://github.com/llvm/llvm-project/issues/102798 --- clang/docs/ReleaseNotes.rst| 2 ++ clang/lib/Frontend/PrintPreprocessedOutput.cpp | 5 ++--- clang/test/Preprocessor/embed_preprocess_to_file.c | 8 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ad1a5e7ae282e..08f8491e2928d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -897,6 +897,8 @@ Bug Fixes in This Version - No longer return ``false`` for ``noexcept`` expressions involving a ``delete`` which resolves to a destroying delete but the type of the object being deleted has a potentially throwing destructor (#GH118660). +- Clang now outputs correct values when #embed data contains bytes with negative + signed char values (#GH102798). Bug Fixes to Compiler Builtins ^^ diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 1005825441b3e..2ae355fb33885 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -974,11 +974,10 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, // Loop over the contents and print them as a comma-delimited list of // values. bool PrintComma = false; - for (auto Iter = Data->BinaryData.begin(), End = Data->BinaryData.end(); - Iter != End; ++Iter) { + for (unsigned char Byte : Data->BinaryData.bytes()) { if (PrintComma) *Callbacks->OS << ", "; -*Callbacks->OS << static_cast(*Iter); +*Callbacks->OS << static_cast(Byte); PrintComma = true; } } else if (Tok.isAnnotation()) { diff --git a/clang/test/Preprocessor/embed_preprocess_to_file.c b/clang/test/Preprocessor/embed_preprocess_to_file.c index 9895d958cf96d..b3c99d36f784a 100644 --- a/clang/test/Preprocessor/embed_preprocess_to_file.c +++ b/clang/test/Preprocessor/embed_preprocess_to_file.c @@ -37,3 +37,11 @@ const char even_more[] = { // DIRECTIVE-NEXT: #embed prefix(4, 5,) suffix(, 6, 7) /* clang -E -dE */ // DIRECTIVE-NEXT: , 8, 9, 10 // DIRECTIVE-NEXT: }; + +constexpr char big_one[] = { +#embed +}; + +// EXPANDED: constexpr char big_one[] = {255 +// DIRECTIVE: constexpr char big_one[] = { +// DIRECTIVE-NEXT: #embed ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix preprocessor output from #embed (#126742) (PR #127222)
https://github.com/Fznamznon milestoned https://github.com/llvm/llvm-project/pull/127222 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Fix preprocessor output from #embed (#126742) (PR #127222)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/127222 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/20.x: [clang] Introduce "binary" StringLiteral for #embed data (#127629) (PR #133460)
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/133460 >From d964cbf7ef72a8d582be37cf074ef3dbaeb5fa33 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Thu, 20 Mar 2025 13:02:29 +0100 Subject: [PATCH 1/2] [clang] Introduce "binary" StringLiteral for #embed data (#127629) StringLiteral is used as internal data of EmbedExpr and we directly use it as an initializer if a single EmbedExpr appears in the initializer list of a char array. It is fast and convenient, but it is causing problems when string literal character values are checked because #embed data values are within a range [0-2^(char width)] but ordinary StringLiteral is of maybe signed char type. This PR introduces new kind of StringLiteral to hold binary data coming from an embedded resource to mitigate these problems. The new kind of StringLiteral is not assumed to have signed char type. The new kind of StringLiteral also helps to prevent crashes when trying to find StringLiteral token locations since these simply do not exist for binary data. Fixes https://github.com/llvm/llvm-project/issues/119256 --- clang/include/clang/AST/Expr.h| 15 --- clang/lib/AST/Expr.cpp| 7 +++ clang/lib/Parse/ParseInit.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 1 + clang/test/Preprocessor/embed_constexpr.c | 21 + 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 clang/test/Preprocessor/embed_constexpr.c diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7be4022649329..06ac0f1704aa9 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1752,7 +1752,14 @@ enum class StringLiteralKind { UTF8, UTF16, UTF32, - Unevaluated + Unevaluated, + // Binary kind of string literal is used for the data coming via #embed + // directive. File's binary contents is transformed to a special kind of + // string literal that in some cases may be used directly as an initializer + // and some features of classic string literals are not applicable to this + // kind of a string literal, for example finding a particular byte's source + // location for better diagnosing. + Binary }; /// StringLiteral - This represents a string literal expression, e.g. "foo" @@ -1884,6 +1891,8 @@ class StringLiteral final int64_t getCodeUnitS(size_t I, uint64_t BitWidth) const { int64_t V = getCodeUnit(I); if (isOrdinary() || isWide()) { + // Ordinary and wide string literals have types that can be signed. + // It is important for checking C23 constexpr initializers. unsigned Width = getCharByteWidth() * BitWidth; llvm::APInt AInt(Width, (uint64_t)V); V = AInt.getSExtValue(); @@ -4965,9 +4974,9 @@ class EmbedExpr final : public Expr { assert(EExpr && CurOffset != ULLONG_MAX && "trying to dereference an invalid iterator"); IntegerLiteral *N = EExpr->FakeChildNode; - StringRef DataRef = EExpr->Data->BinaryData->getBytes(); N->setValue(*EExpr->Ctx, - llvm::APInt(N->getValue().getBitWidth(), DataRef[CurOffset], + llvm::APInt(N->getValue().getBitWidth(), + EExpr->Data->BinaryData->getCodeUnit(CurOffset), N->getType()->isSignedIntegerType())); // We want to return a reference to the fake child node in the // EmbedExpr, not the local variable N. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 06b0491442673..c43301dbcb120 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1104,6 +1104,7 @@ unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target, switch (SK) { case StringLiteralKind::Ordinary: case StringLiteralKind::UTF8: + case StringLiteralKind::Binary: CharByteWidth = Target.getCharWidth(); break; case StringLiteralKind::Wide: @@ -1216,6 +1217,7 @@ void StringLiteral::outputString(raw_ostream &OS) const { switch (getKind()) { case StringLiteralKind::Unevaluated: case StringLiteralKind::Ordinary: + case StringLiteralKind::Binary: break; // no prefix. case StringLiteralKind::Wide: OS << 'L'; @@ -1332,6 +1334,11 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken, unsigned *StartTokenByteOffset) const { + // No source location of bytes for binary literals since they don't come from + // source. + if (getKind() == StringLiteralKind::Binary) +return getStrTokenLoc(0); + assert((getKind() == StringLiteralKind::Ordinary || getKind() == StringLiteralKind::UTF8 || getKind() == StringLiteralKind::Unevaluated) && diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Pa
[llvm-branch-commits] [clang] release/20.x: [clang] Introduce "binary" StringLiteral for #embed data (#127629) (PR #133460)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/133460 StringLiteral is used as internal data of EmbedExpr and we directly use it as an initializer if a single EmbedExpr appears in the initializer list of a char array. It is fast and convenient, but it is causing problems when string literal character values are checked because #embed data values are within a range [0-2^(char width)] but ordinary StringLiteral is of maybe signed char type. This PR introduces new kind of StringLiteral to hold binary data coming from an embedded resource to mitigate these problems. The new kind of StringLiteral is not assumed to have signed char type. The new kind of StringLiteral also helps to prevent crashes when trying to find StringLiteral token locations since these simply do not exist for binary data. >From d964cbf7ef72a8d582be37cf074ef3dbaeb5fa33 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Thu, 20 Mar 2025 13:02:29 +0100 Subject: [PATCH 1/2] [clang] Introduce "binary" StringLiteral for #embed data (#127629) StringLiteral is used as internal data of EmbedExpr and we directly use it as an initializer if a single EmbedExpr appears in the initializer list of a char array. It is fast and convenient, but it is causing problems when string literal character values are checked because #embed data values are within a range [0-2^(char width)] but ordinary StringLiteral is of maybe signed char type. This PR introduces new kind of StringLiteral to hold binary data coming from an embedded resource to mitigate these problems. The new kind of StringLiteral is not assumed to have signed char type. The new kind of StringLiteral also helps to prevent crashes when trying to find StringLiteral token locations since these simply do not exist for binary data. Fixes https://github.com/llvm/llvm-project/issues/119256 --- clang/include/clang/AST/Expr.h| 15 --- clang/lib/AST/Expr.cpp| 7 +++ clang/lib/Parse/ParseInit.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 1 + clang/test/Preprocessor/embed_constexpr.c | 21 + 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 clang/test/Preprocessor/embed_constexpr.c diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7be4022649329..06ac0f1704aa9 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1752,7 +1752,14 @@ enum class StringLiteralKind { UTF8, UTF16, UTF32, - Unevaluated + Unevaluated, + // Binary kind of string literal is used for the data coming via #embed + // directive. File's binary contents is transformed to a special kind of + // string literal that in some cases may be used directly as an initializer + // and some features of classic string literals are not applicable to this + // kind of a string literal, for example finding a particular byte's source + // location for better diagnosing. + Binary }; /// StringLiteral - This represents a string literal expression, e.g. "foo" @@ -1884,6 +1891,8 @@ class StringLiteral final int64_t getCodeUnitS(size_t I, uint64_t BitWidth) const { int64_t V = getCodeUnit(I); if (isOrdinary() || isWide()) { + // Ordinary and wide string literals have types that can be signed. + // It is important for checking C23 constexpr initializers. unsigned Width = getCharByteWidth() * BitWidth; llvm::APInt AInt(Width, (uint64_t)V); V = AInt.getSExtValue(); @@ -4965,9 +4974,9 @@ class EmbedExpr final : public Expr { assert(EExpr && CurOffset != ULLONG_MAX && "trying to dereference an invalid iterator"); IntegerLiteral *N = EExpr->FakeChildNode; - StringRef DataRef = EExpr->Data->BinaryData->getBytes(); N->setValue(*EExpr->Ctx, - llvm::APInt(N->getValue().getBitWidth(), DataRef[CurOffset], + llvm::APInt(N->getValue().getBitWidth(), + EExpr->Data->BinaryData->getCodeUnit(CurOffset), N->getType()->isSignedIntegerType())); // We want to return a reference to the fake child node in the // EmbedExpr, not the local variable N. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 06b0491442673..c43301dbcb120 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1104,6 +1104,7 @@ unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target, switch (SK) { case StringLiteralKind::Ordinary: case StringLiteralKind::UTF8: + case StringLiteralKind::Binary: CharByteWidth = Target.getCharWidth(); break; case StringLiteralKind::Wide: @@ -1216,6 +1217,7 @@ void StringLiteral::outputString(raw_ostream &OS) const { switch (getKind()) { case StringLiteralKind::Unevaluated: case StringLiteralKind::Ordinary: + case StringLiteralKind::Binary: break; // no prefix. case StringLite
[llvm-branch-commits] [clang] [clang] Fix preprocessor output from #embed (#126742) (PR #127222)
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/127222 >From 95cf7310c15324f25e9e5276772278fa58ba6926 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Thu, 13 Feb 2025 10:59:21 +0100 Subject: [PATCH] [clang] Fix preprocessor output from #embed (#126742) When bytes with negative signed char values appear in the data, make sure to use raw bytes from the data string when preprocessing, not char values. Fixes https://github.com/llvm/llvm-project/issues/102798 --- clang/docs/ReleaseNotes.rst| 2 ++ clang/lib/Frontend/PrintPreprocessedOutput.cpp | 5 ++--- clang/test/Preprocessor/embed_preprocess_to_file.c | 8 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ad1a5e7ae282e..08f8491e2928d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -897,6 +897,8 @@ Bug Fixes in This Version - No longer return ``false`` for ``noexcept`` expressions involving a ``delete`` which resolves to a destroying delete but the type of the object being deleted has a potentially throwing destructor (#GH118660). +- Clang now outputs correct values when #embed data contains bytes with negative + signed char values (#GH102798). Bug Fixes to Compiler Builtins ^^ diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 1005825441b3e..2ae355fb33885 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -974,11 +974,10 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, // Loop over the contents and print them as a comma-delimited list of // values. bool PrintComma = false; - for (auto Iter = Data->BinaryData.begin(), End = Data->BinaryData.end(); - Iter != End; ++Iter) { + for (unsigned char Byte : Data->BinaryData.bytes()) { if (PrintComma) *Callbacks->OS << ", "; -*Callbacks->OS << static_cast(*Iter); +*Callbacks->OS << static_cast(Byte); PrintComma = true; } } else if (Tok.isAnnotation()) { diff --git a/clang/test/Preprocessor/embed_preprocess_to_file.c b/clang/test/Preprocessor/embed_preprocess_to_file.c index 9895d958cf96d..b3c99d36f784a 100644 --- a/clang/test/Preprocessor/embed_preprocess_to_file.c +++ b/clang/test/Preprocessor/embed_preprocess_to_file.c @@ -37,3 +37,11 @@ const char even_more[] = { // DIRECTIVE-NEXT: #embed prefix(4, 5,) suffix(, 6, 7) /* clang -E -dE */ // DIRECTIVE-NEXT: , 8, 9, 10 // DIRECTIVE-NEXT: }; + +constexpr char big_one[] = { +#embed +}; + +// EXPANDED: constexpr char big_one[] = {255 +// DIRECTIVE: constexpr char big_one[] = { +// DIRECTIVE-NEXT: #embed ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/20.x: [clang] Introduce "binary" StringLiteral for #embed data (#127629) (PR #133460)
https://github.com/Fznamznon milestoned https://github.com/llvm/llvm-project/pull/133460 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/20.x: [clang] Introduce "binary" StringLiteral for #embed data (#127629) (PR #133460)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/133460 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits