[clang] [Clang] Defaults `-Wunicode-whitespace` to an error. (PR #210945)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 21 06:53:47 PDT 2026
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/210945
>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 1/4] [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}}
>From c3ea9f998765800404f3c60a06b1233cf991c803 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 21 Jul 2026 14:12:00 +0200
Subject: [PATCH 2/4] fix typo
---
clang/docs/ReleaseNotes.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 8e79ec77198a0..22df56712fad9 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -48,7 +48,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
- `-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
+Clang will stop accepting non-ascii whitespaces as token separators
in a future version of Clang.
### C++ Specific Potentially Breaking Changes
>From bd45df9becc05ae78352a1165a3c89c1c7440a81 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 21 Jul 2026 14:27:59 +0200
Subject: [PATCH 3/4] fix diag message
---
clang/include/clang/Basic/DiagnosticLexKinds.td | 2 +-
clang/test/Lexer/unicode.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 3995c757b99c4..fc3087d5ed21b 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -137,7 +137,7 @@ 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 character <U+%0> as whitespace">,
+ "treating character %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 "
diff --git a/clang/test/Lexer/unicode.c b/clang/test/Lexer/unicode.c
index 4e71cdaed772a..11a03a7493d28 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-error {{treating character <U+' ' U+00A0> as whitespace}}
-extern int x; // expected-error {{treating character <U+' ' U+3000> as whitespace}}
+extern int x; // expected-error {{treating character ' ' U+00A0 as whitespace}}
+extern int x; // expected-error {{treating character ' ' U+3000 as whitespace}}
// CHECK: extern int {{x}}
// CHECK: extern int {{x}}
>From 27b38f9bc6fb5fc8bc74494c70bbabd378dbbb48 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 21 Jul 2026 15:53:31 +0200
Subject: [PATCH 4/4] format
---
clang/lib/Lex/Lexer.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 07ddb18c52de7..d673752f264bb 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3778,8 +3778,8 @@ 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);
+ << EscapeSingleCodepointForDiagnostic(C)
+ << makeCharRange(*this, BufferPtr, CurPtr);
Result.setFlag(Token::LeadingSpace);
return true;
More information about the cfe-commits
mailing list