[clang] [Clang] Defaults `-Wunicode-whitespace` to an error. (PR #210945)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 21 03:56:30 PDT 2026
https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/210945
Clang accepts some Unicode whitespaces in some context. There are a few issues with this:
- The support is incomplete and inconsistent, as illustrated in #38934
- We are not consistent with the Unicode specs (tr1, tr55) in that we treat U+0028/0+0029 as horizontal separators while Unicode consider them vertical.
Ultimately, Unicode whitespaces are more likely than not unintended.
Neither GCC nor MSVC support this extension.
Fixes #38934.
>From 9c66ee3a15d800101d63a02152ed5d567229822c Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 21 Jul 2026 12:39:29 +0200
Subject: [PATCH] [Clang] Defaults `-Wunicode-whitespace` to an error.
Clang accepts some Unicode whitespaces in some context.
There are a few issues with this:
- The support is incomplete and inconsistant, as illustrated in #38934
- We are not consistent with the Unicode specs (tr1, tr55)
in that we treat U+0028/0+0029 as horizontal separators while
Unicode consider them vertical.
Ultimately, Unicode whitespaces are more likely than not
unintended.
Neither GCC nor MSVC support this extension.
Fixes #38934.
---
clang/docs/ReleaseNotes.md | 5 +++++
clang/include/clang/Basic/DiagnosticLexKinds.td | 4 ++--
clang/lib/Lex/Lexer.cpp | 1 +
clang/test/Analysis/mig.mm | 2 +-
clang/test/Lexer/unicode.c | 4 ++--
5 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 9301745b9628e..8e79ec77198a0 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -46,6 +46,11 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
### C/C++ Language Potentially Breaking Changes
+- `-Wunicode-whitespace` now defaults to an error.
+The previous behavior can be restored with `-Wno-error=unicode-whitespace`.
+Clang will stop accepting non-ascii whitespaces as token seperator
+in a future version of Clang.
+
### C++ Specific Potentially Breaking Changes
### ABI Changes in This Version
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 79e74a846e3ea..3995c757b99c4 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -137,8 +137,8 @@ def err_character_not_allowed : Error<
def err_character_not_allowed_identifier : Error<
"character <U+%0> not allowed %select{in|at the start of}1 an identifier">;
def ext_unicode_whitespace : ExtWarn<
- "treating Unicode character as whitespace">,
- InGroup<DiagGroup<"unicode-whitespace">>;
+ "treating character <U+%0> as whitespace">,
+ InGroup<DiagGroup<"unicode-whitespace">>, DefaultError;
def warn_utf8_symbol_homoglyph : Warning<
"treating Unicode character <U+%0> as an identifier character rather than "
"as '%1' symbol">, InGroup<DiagGroup<"unicode-homoglyph">>;
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index d5085ca6d4c8a..07ddb18c52de7 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3778,6 +3778,7 @@ bool Lexer::CheckUnicodeWhitespace(Token &Result, uint32_t C,
if (!isLexingRawMode() && !PP->isPreprocessedOutput() &&
isUnicodeWhitespace(C)) {
Diag(BufferPtr, diag::ext_unicode_whitespace)
+ << EscapeSingleCodepointForDiagnostic(C)
<< makeCharRange(*this, BufferPtr, CurPtr);
Result.setFlag(Token::LeadingSpace);
diff --git a/clang/test/Analysis/mig.mm b/clang/test/Analysis/mig.mm
index e8d08f355d3ea..954eccc1a01ca 100644
--- a/clang/test/Analysis/mig.mm
+++ b/clang/test/Analysis/mig.mm
@@ -166,7 +166,7 @@ void test_block() {
^MIG_SERVER_ROUTINE (mach_port_name_t port,
vm_address_t address, vm_size_t size) {
vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
- return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
// expected-note at -1{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
};
}
diff --git a/clang/test/Lexer/unicode.c b/clang/test/Lexer/unicode.c
index 5add2e49e4dfb..4e71cdaed772a 100644
--- a/clang/test/Lexer/unicode.c
+++ b/clang/test/Lexer/unicode.c
@@ -7,8 +7,8 @@
// This file contains Unicode characters; please do not "fix" them!
-extern int x; // expected-warning {{treating Unicode character as whitespace}}
-extern int x; // expected-warning {{treating Unicode character as whitespace}}
+extern int x; // expected-error {{treating character <U+' ' U+00A0> as whitespace}}
+extern int x; // expected-error {{treating character <U+' ' U+3000> as whitespace}}
// CHECK: extern int {{x}}
// CHECK: extern int {{x}}
More information about the cfe-commits
mailing list