[clang] [Clang] Fixed a crash when parsing #embed parameters with unmatched closing brackets (PR #152877)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 9 13:03:47 PDT 2025
https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/152877
Fixes #152829
---
This patch addresses the issue where the preprocessor could crash when parsing `#embed` parameters containing unmatched closing brackets
```cpp
#embed "file" prefix(])
#embed "file" prefix(})
```
>From 6bb7069f535c129157254bbeff8d44972baadbc5 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sat, 9 Aug 2025 22:59:29 +0300
Subject: [PATCH] [Clang] Fixed a crash when parsing #embed parameters with
unmatched closing brackets
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Lex/PPDirectives.cpp | 6 +++++-
clang/test/Preprocessor/embed_parsing_errors.c | 9 +++++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0e9fcaa5fac6a..837ef80f07e87 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -282,6 +282,7 @@ Crash and bug fixes
^^^^^^^^^^^^^^^^^^^
- Fixed a crash in the static analyzer that when the expression in an
``[[assume(expr)]]`` attribute was enclosed in parentheses. (#GH151529)
+- Fixed a crash when parsing ``#embed`` parameters with unmatched closing brackets. (#GH152829)
Improvements
^^^^^^^^^^^^
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 3fa060f7ec1bd..9d01b8d99e227 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -3793,9 +3793,13 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
[[fallthrough]];
case tok::r_brace:
case tok::r_square: {
+ if (BracketStack.empty()) {
+ ExpectOrDiagAndSkipToEOD(tok::r_paren);
+ return false;
+ }
tok::TokenKind Matching =
GetMatchingCloseBracket(BracketStack.back().first);
- if (BracketStack.empty() || CurTok.getKind() != Matching) {
+ if (CurTok.getKind() != Matching) {
DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
return false;
}
diff --git a/clang/test/Preprocessor/embed_parsing_errors.c b/clang/test/Preprocessor/embed_parsing_errors.c
index 490ec6d4ded2c..a8bbdea91eb16 100644
--- a/clang/test/Preprocessor/embed_parsing_errors.c
+++ b/clang/test/Preprocessor/embed_parsing_errors.c
@@ -94,6 +94,9 @@ char buffer[] = {
#embed "embed_parsing_errors.c" prefix() // OK: tokens within parens are optional
#embed "embed_parsing_errors.c" prefix)
// expected-error at -1 {{expected '('}}
+#embed "embed_parsing_errors.c" prefix()) // expected-error {{expected identifier}}
+#embed "embed_parsing_errors.c" prefix(]) // expected-error {{expected ')'}}
+#embed "embed_parsing_errors.c" prefix(}) // expected-error {{expected ')'}}
#embed "embed_parsing_errors.c" suffix
// expected-error at -1 {{expected '('}}
@@ -115,6 +118,9 @@ char buffer[] = {
#embed "embed_parsing_errors.c" suffix() // OK: tokens within parens are optional
#embed "embed_parsing_errors.c" suffix)
// expected-error at -1 {{expected '('}}
+#embed "embed_parsing_errors.c" suffix()) // expected-error {{expected identifier}}
+#embed "embed_parsing_errors.c" suffix(]) // expected-error {{expected ')'}}
+#embed "embed_parsing_errors.c" suffix(}) // expected-error {{expected ')'}}
#embed "embed_parsing_errors.c" if_empty(1/0) // OK: emitted as tokens, not evaluated yet.
#embed "embed_parsing_errors.c" if_empty(([{}])) // OK: delimiters balanced
@@ -128,3 +134,6 @@ char buffer[] = {
#embed "embed_parsing_errors.c" if_empty)
// expected-error at -1 {{expected '('}}
};
+#embed "embed_parsing_errors.c" if_empty()) // expected-error {{expected identifier}}
+#embed "embed_parsing_errors.c" if_empty(]) // expected-error {{expected ')'}}
+#embed "embed_parsing_errors.c" if_empty(}) // expected-error {{expected ')'}}
More information about the cfe-commits
mailing list