[clang] [clang][Lex] Don't diagnose unterminated or empty quotes in -traditional-cpp (PR #221994)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 06:15:50 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Kiroo (Chanung) (zlfn)
<details>
<summary>Changes</summary>
GCC does not diagnose unbalanced or empty quotes in -traditional-cpp mode, where they are ordinary text rather than the start of a literal, but Clang's lexer did. Match GCC by suppressing those diagnostics when TraditionalCPP is set.
Only the diagnostics are suppressed; the lexer still forms a tok::unknown token, so genuinely broken input is still rejected.
Fixes #<!-- -->142327
---
Full diff: https://github.com/llvm/llvm-project/pull/221994.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.md (+3)
- (modified) clang/lib/Lex/Lexer.cpp (+6-3)
- (added) clang/test/Preprocessor/traditional-cpp-quotes.c (+11)
``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a43ed2b924622..12046f0772edf 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -482,6 +482,9 @@ features cannot lower the translation-unit ABI level;
dimension that is a zero integer constant, as in `struct Empty vla[n]` or
`int vla[n][0]`. (#GH28328)
+- Clang no longer diagnoses unbalanced or empty quotes in `-traditional-cpp`
+ mode, matching GCC's behavior. (#GH142327)
+
### Improvements to Clang's time-trace
### Improvements to Coverage Mapping
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 4762b38e67c00..4f54a0dd0bcd3 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2341,7 +2341,8 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor &&
+ !LangOpts.TraditionalCPP)
Diag(BufferPtr, diag::ext_unterminated_char_or_string) << 1;
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return true;
@@ -2564,7 +2565,8 @@ bool Lexer::LexCharConstant(Token &Result, const char *CurPtr,
char C = getAndAdvanceChar(CurPtr, Result);
if (C == '\'') {
- if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor &&
+ !LangOpts.TraditionalCPP)
Diag(BufferPtr, diag::ext_empty_character);
FormTokenWithChars(Result, CurPtr, tok::unknown);
return true;
@@ -2577,7 +2579,8 @@ bool Lexer::LexCharConstant(Token &Result, const char *CurPtr,
if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor &&
+ !LangOpts.TraditionalCPP)
Diag(BufferPtr, diag::ext_unterminated_char_or_string) << 0;
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return true;
diff --git a/clang/test/Preprocessor/traditional-cpp-quotes.c b/clang/test/Preprocessor/traditional-cpp-quotes.c
new file mode 100644
index 0000000000000..9eaa5f9766532
--- /dev/null
+++ b/clang/test/Preprocessor/traditional-cpp-quotes.c
@@ -0,0 +1,11 @@
+/* RUN: %clang_cc1 -traditional-cpp -E -verify %s
+ * expected-no-diagnostics
+ */
+
+/* -traditional-cpp is mainly used to preprocess non-source files, where an
+ * unbalanced quote is ordinary text rather than the start of a literal.
+ * GCC does not diagnose these either. */
+// Test "double
+// Try 'single
+he said '' and left
+don't
``````````
</details>
https://github.com/llvm/llvm-project/pull/221994
More information about the cfe-commits
mailing list