[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