[clang] 8f0c865 - Fix a crash with empty escape sequences when lexing (#102339)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 8 04:32:42 PDT 2024
Author: Aaron Ballman
Date: 2024-08-08T07:32:39-04:00
New Revision: 8f0c865d1024a9ff7f3f1b0d3e47a6c9f5f672c2
URL: https://github.com/llvm/llvm-project/commit/8f0c865d1024a9ff7f3f1b0d3e47a6c9f5f672c2
DIFF: https://github.com/llvm/llvm-project/commit/8f0c865d1024a9ff7f3f1b0d3e47a6c9f5f672c2.diff
LOG: Fix a crash with empty escape sequences when lexing (#102339)
The utilities we use for lexing string and character literals can be run
in a mode where we pass a null pointer for the diagnostics engine. This
mode is used by the format string checkers, for example. However, there
were two places that failed to account for a null diagnostic engine
pointer: `\o{}` and `\x{}`.
This patch adds a check for a null pointer and correctly handles
fallback behavior.
Fixes #102218
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Lex/LiteralSupport.cpp
clang/test/Lexer/char-escapes-delimited.c
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ffdb5f8f5af3ed..a355b8db11faf0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -175,6 +175,8 @@ Bug Fixes in This Version
be used in C++.
- Fixed a failed assertion when checking required literal types in C context. (#GH101304).
- Fixed a crash when trying to transform a dependent address space type. Fixes #GH101685.
+- Fixed a crash when diagnosing format strings and encountering an empty
+ delimited escape sequence (e.g., ``"\o{}"``). #GH102218
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 9d2720af5dbd92..225a6c2d15baaa 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -190,9 +190,10 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin,
Delimited = true;
ThisTokBuf++;
if (*ThisTokBuf == '}') {
- Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
- diag::err_delimited_escape_empty);
- return ResultChar;
+ HadError = true;
+ if (Diags)
+ Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
+ diag::err_delimited_escape_empty);
}
} else if (ThisTokBuf == ThisTokEnd || !isHexDigit(*ThisTokBuf)) {
if (Diags)
@@ -283,9 +284,10 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin,
Delimited = true;
++ThisTokBuf;
if (*ThisTokBuf == '}') {
- Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
- diag::err_delimited_escape_empty);
- return ResultChar;
+ HadError = true;
+ if (Diags)
+ Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
+ diag::err_delimited_escape_empty);
}
while (ThisTokBuf != ThisTokEnd) {
diff --git a/clang/test/Lexer/char-escapes-delimited.c b/clang/test/Lexer/char-escapes-delimited.c
index 5327ef700b0e25..7a8986bc5f8679 100644
--- a/clang/test/Lexer/char-escapes-delimited.c
+++ b/clang/test/Lexer/char-escapes-delimited.c
@@ -123,3 +123,16 @@ void separators(void) {
static_assert('\N??<DOLLAR SIGN??>' == '$'); // expected-warning 2{{trigraph converted}} \
// ext-warning {{extension}} cxx23-warning {{C++23}}
#endif
+
+void GH102218(void) {
+ // The format specifier checking code runs the lexer with diagnostics
+ // disabled. This used to crash Clang for malformed \o and \x because the
+ // lexer missed a null pointer check for the diagnostics engine in that case.
+ extern int printf(const char *, ...);
+ printf("\o{}"); // expected-error {{delimited escape sequence cannot be empty}}
+ printf("\x{}"); // expected-error {{delimited escape sequence cannot be empty}}
+
+ // These cases always worked but are here for completeness.
+ printf("\u{}"); // expected-error {{delimited escape sequence cannot be empty}}
+ printf("\N{}"); // expected-error {{delimited escape sequence cannot be empty}}
+}
More information about the cfe-commits
mailing list