[clang] [C++26] Implement P2843R3 - Preprocessing is never undefined (define/undef keyword part) (PR #218322)
Yihan Wang via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 23 22:47:01 PDT 2026
https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/218322
This PR implement [P2843R3 - Preprocessing is never undefined](https://wg21.link/P2843) `define`/`undef` keyword part.
The two major changes in this patch:
- Error-by-default warning for `#define` keyword.
- Pedantic warning for `#undef` keyword.
RFC: https://discourse.llvm.org/t/rfc-default-on-diagnostics-for-implement-p2843r3-preprocessing-is-never-undefined/90863
>From ac925ed27622ca13c93d09255044be33ce679744 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Sun, 23 Aug 2026 22:41:55 -0700
Subject: [PATCH] [C++26] Implement P2843R3 - Preprocessing is never undefined
(define/undef keyword part)
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/docs/ReleaseNotes.md | 7 ++++
clang/include/clang/Basic/DiagnosticGroups.td | 3 +-
.../include/clang/Basic/DiagnosticLexKinds.td | 5 ++-
clang/lib/Lex/PPDirectives.cpp | 14 +++++--
clang/test/C/drs/dr1xx.c | 2 +-
clang/test/CXX/cpp/cpp.replace.general/p9.cpp | 38 +++++++++++++++++++
clang/test/CXX/drs/cwg3088.cpp | 14 +++----
clang/test/Preprocessor/macro-reserved.c | 30 +++++++--------
clang/test/Preprocessor/macro-reserved.cpp | 28 +++++++-------
.../test/Preprocessor/warn-macro-undef-true.c | 8 +---
clang/test/Sema/c++-keyword-in-c.c | 8 ++--
clang/test/SemaCUDA/noinline.cu | 2 +-
clang/test/SemaCXX/abstract.cpp | 1 +
clang/test/SemaCXX/consteval-builtin.cpp | 2 +-
clang/test/SemaTemplate/instantiate-array.cpp | 2 +-
clang/www/cxx_status.html | 14 ++++++-
16 files changed, 122 insertions(+), 56 deletions(-)
create mode 100644 clang/test/CXX/cpp/cpp.replace.general/p9.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index ca0dbfa2af229..f39be8ab74946 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -416,6 +416,13 @@ features cannot lower the translation-unit ABI level;
- `-Wc++98-compat` now diagnoses explicit conversion functions in C++20 and
later, matching the behavior in C++11 through C++17. (#GH161689)
+- `-Wkeyword-macro` is now enabled by default for `#define` directives whose
+ macro name is a keyword or an identifier with special meaning. The
+ corresponding `#undef` diagnostic is not enabled by default; it is enabled by
+ `-pedantic`, `-Wkeyword-macro`, or its more specific
+ `-Wkeyword-macro-undef` subgroup.
+
+
### Improvements to Clang's time-trace
### Improvements to Coverage Mapping
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 9ee0b61a96a32..d5ef1270bf4bc 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1127,7 +1127,8 @@ def : DiagGroup<"sequence-point", [Unsequenced]>;
// Preprocessor warnings.
def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
-def KeywordAsMacro : DiagGroup<"keyword-macro">;
+def KeywordAsMacroUndef : DiagGroup<"keyword-macro-undef">;
+def KeywordAsMacro : DiagGroup<"keyword-macro", [KeywordAsMacroUndef]>;
def ReservedIdAsMacro : DiagGroup<"reserved-macro-identifier">;
def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", [ReservedIdAsMacro]>;
def ReservedAttributeIdentifier : DiagGroup<"reserved-attribute-identifier">;
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index bdb78ed80b7b4..49013756b2dfd 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -435,8 +435,11 @@ def note_pp_ambiguous_macro_chosen : Note<
"expanding this definition of %0">;
def note_pp_ambiguous_macro_other : Note<
"other definition of %0">;
-def warn_pp_macro_hides_keyword : Extension<
+def warn_pp_macro_hides_keyword : ExtWarn<
"keyword is hidden by macro definition">, InGroup<KeywordAsMacro>;
+def ext_pp_macro_name_is_keyword : Extension<
+ "keyword or identifier with special meaning is used as a macro name">,
+ InGroup<KeywordAsMacroUndef>;
def warn_pp_macro_is_reserved_id : Warning<
"macro name is a reserved identifier">, DefaultIgnore,
InGroup<ReservedIdAsMacro>;
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 29236bd0f4782..5bca4f4ce6578 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -103,8 +103,10 @@ SourceRange Preprocessor::DiscardUntilEndOfDirective(
/// Enumerates possible cases of #define/#undef a reserved identifier.
enum MacroDiag {
- MD_NoWarn, //> Not a reserved identifier
- MD_KeywordDef, //> Macro hides keyword, enabled by default
+ MD_NoWarn, //> Not a reserved identifier
+ MD_KeywordDef, //> Macro hides keyword, enabled by default
+ MD_KeywordUnDef, //> Undef keyword, It is generally harmless and widely used,
+ //> enabled in pedantic mode.
MD_ReservedMacro, //> #define of #undef reserved id, disabled by default
MD_ReservedAttributeIdentifier
};
@@ -213,7 +215,11 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) {
const LangOptions &Lang = PP.getLangOpts();
- // Do not warn on keyword undef. It is generally harmless and widely used.
+ StringRef Text = II->getName();
+ if (II->isKeyword(Lang))
+ return MD_KeywordUnDef;
+ if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))
+ return MD_KeywordUnDef;
if (isReservedInAllContexts(II->isReserved(Lang)))
return MD_ReservedMacro;
if (isReservedCXXAttributeName(PP, II))
@@ -412,6 +418,8 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
if (ShadowFlag)
*ShadowFlag = true;
}
+ if (D == MD_KeywordUnDef)
+ Diag(MacroNameTok, diag::ext_pp_macro_name_is_keyword);
if (D == MD_ReservedMacro)
Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
if (D == MD_ReservedAttributeIdentifier)
diff --git a/clang/test/C/drs/dr1xx.c b/clang/test/C/drs/dr1xx.c
index 055a30cc9c4b8..1704aa0a361d3 100644
--- a/clang/test/C/drs/dr1xx.c
+++ b/clang/test/C/drs/dr1xx.c
@@ -160,7 +160,7 @@ void dr106(void *p, int i) {
void dr108(void) {
#define const
const int i = 12;
-#undef const
+#undef const /* expected-warning {{keyword or identifier with special meaning is used as a macro name}} */
const int j = 12; /* expected-note {{variable 'j' declared const here}} */
i = 100; /* Okay, the keyword was hidden by the macro. */
diff --git a/clang/test/CXX/cpp/cpp.replace.general/p9.cpp b/clang/test/CXX/cpp/cpp.replace.general/p9.cpp
new file mode 100644
index 0000000000000..7d775939063a2
--- /dev/null
+++ b/clang/test/CXX/cpp/cpp.replace.general/p9.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++26 -fsyntax-only -verify=default %s
+// RUN: %clang_cc1 -std=c++26 -pedantic -fsyntax-only -verify=pedantic %s
+// RUN: %clang_cc1 -std=c++26 -pedantic -Wno-keyword-macro-undef -fsyntax-only -verify=default %s
+// RUN: %clang_cc1 -std=c++26 -pedantic-errors -fsyntax-only -verify=pedantic-errors %s
+
+// [cpp.replace.general]/p9: A translation unit shall not #define or #undef
+// macro names lexically identical to keywords ([lex.key]) or to the identifiers
+// listed in Table 4.
+#define for 0
+// default-warning at -1 {{keyword is hidden by macro definition}}
+// pedantic-warning at -2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error at -3 {{keyword is hidden by macro definition}}
+#undef for
+// pedantic-warning at -1 {{keyword or identifier with special meaning is used as a macro name}}
+// pedantic-errors-error at -2 {{keyword or identifier with special meaning is used as a macro name}}
+
+#define final 1
+// default-warning at -1 {{keyword is hidden by macro definition}}
+// pedantic-warning at -2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error at -3 {{keyword is hidden by macro definition}}
+#undef final
+// pedantic-warning at -1 {{keyword or identifier with special meaning is used as a macro name}}
+// pedantic-errors-error at -2 {{keyword or identifier with special meaning is used as a macro name}}
+
+#define override
+// default-warning at -1 {{keyword is hidden by macro definition}}
+// pedantic-warning at -2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error at -3 {{keyword is hidden by macro definition}}
+#undef override
+// pedantic-warning at -1 {{keyword or identifier with special meaning is used as a macro name}}
+// pedantic-errors-error at -2 {{keyword or identifier with special meaning is used as a macro name}}
+
+// Empty definitions of qualifier keywords are accepted for compatibility with
+// configuration scripts, but #undef is still diagnosed in pedantic modes.
+#define const
+#undef const
+// pedantic-warning at -1 {{keyword or identifier with special meaning is used as a macro name}}
+// pedantic-errors-error at -2 {{keyword or identifier with special meaning is used as a macro name}}
diff --git a/clang/test/CXX/drs/cwg3088.cpp b/clang/test/CXX/drs/cwg3088.cpp
index 04333d8f91a46..39c02dd31fc6c 100644
--- a/clang/test/CXX/drs/cwg3088.cpp
+++ b/clang/test/CXX/drs/cwg3088.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected
-// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++14 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++17 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++20 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx20
-// RUN: %clang_cc1 -std=c++23 -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx20
-// RUN: %clang_cc1 -std=c++2c -fexceptions -fcxx-exceptions -pedantic-errors %s -verify-directives -verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++98 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++14 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++17 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++20 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++23 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++2c -fexceptions -fcxx-exceptions -pedantic-errors -Wno-keyword-macro-undef %s -verify-directives -verify=expected,since-cxx11,since-cxx20
// The list of keywords was taken fron [lex.key] for C++98, and the difference
// between [lex.key] contents in N and N-1 revisions of the Standard otherwise.
diff --git a/clang/test/Preprocessor/macro-reserved.c b/clang/test/Preprocessor/macro-reserved.c
index 6026a9f60730e..875fce19513c6 100644
--- a/clang/test/Preprocessor/macro-reserved.c
+++ b/clang/test/Preprocessor/macro-reserved.c
@@ -9,7 +9,7 @@
#define __STDC__ 1 // expected-warning {{redefining builtin macro}}
#define __clang__ 1
-#undef for
+#undef for // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#undef final
#undef __HAVE_X
#undef __cplusplus
@@ -30,30 +30,30 @@
#define extern
#define inline
-#undef while
-#undef const
-#undef static
-#undef extern
-#undef inline
+#undef while // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef const // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef static // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline __inline
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline __inline__
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline inline__ // expected-warning {{keyword is hidden by macro definition}}
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __inline // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __extern // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __extern__ // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline _inline // expected-warning {{keyword is hidden by macro definition}}
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define volatile // expected-warning {{keyword is hidden by macro definition}}
-#undef volatile
+#undef volatile // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#pragma clang diagnostic warning "-Wreserved-macro-identifier"
@@ -64,7 +64,7 @@
#define _HAVE_X 0 // expected-warning {{macro name is a reserved identifier}}
#define X__Y
-#undef switch
+#undef switch // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#undef final
#undef __cplusplus // expected-warning {{macro name is a reserved identifier}}
#undef _HAVE_X // expected-warning {{macro name is a reserved identifier}}
diff --git a/clang/test/Preprocessor/macro-reserved.cpp b/clang/test/Preprocessor/macro-reserved.cpp
index 53bb3634bac4c..a90966dc180dd 100644
--- a/clang/test/Preprocessor/macro-reserved.cpp
+++ b/clang/test/Preprocessor/macro-reserved.cpp
@@ -6,7 +6,7 @@
#define _HAVE_X 0
#define X__Y
-#undef for
+#undef for // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#undef final
#undef __HAVE_X
#undef _HAVE_X
@@ -22,30 +22,30 @@
#define extern
#define inline
-#undef while
-#undef const
-#undef static
-#undef extern
-#undef inline
+#undef while // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef const // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef static // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline __inline
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline __inline__
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline inline__ // expected-warning {{keyword is hidden by macro definition}}
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __inline // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __extern // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define extern __extern__ // expected-warning {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define inline _inline // expected-warning {{keyword is hidden by macro definition}}
-#undef inline
+#undef inline // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#define volatile // expected-warning {{keyword is hidden by macro definition}}
-#undef volatile
+#undef volatile // expected-warning {{keyword or identifier with special meaning is used as a macro name}}
#pragma clang diagnostic warning "-Wreserved-macro-identifier"
diff --git a/clang/test/Preprocessor/warn-macro-undef-true.c b/clang/test/Preprocessor/warn-macro-undef-true.c
index 9a64d577a96ed..e87b2d34f59cb 100644
--- a/clang/test/Preprocessor/warn-macro-undef-true.c
+++ b/clang/test/Preprocessor/warn-macro-undef-true.c
@@ -2,11 +2,7 @@
// RUN: %clang_cc1 %s -Eonly -std=c99 -verify=undef-true
// RUN: %clang_cc1 %s -Eonly -std=c11 -verify=undef-true
// RUN: %clang_cc1 %s -Eonly -std=c17 -verify=undef-true
-// RUN: %clang_cc1 %s -Eonly -std=c23 -verify=undef-true
-
-#if __STDC_VERSION__ >= 202311L
-/* undef-true-no-diagnostics */
-#endif
+// RUN: %clang_cc1 %s -Eonly -std=c23 -verify=undef-true,c23-keyword
#define FOO true
#if FOO /* #1 */
@@ -27,7 +23,7 @@
/* undef-true-warning@#3 {{'true' is not defined, evaluates to 0}} */
#endif
-#define true 1
+#define true 1 /* c23-keyword-warning {{keyword is hidden by macro definition}} */
#define FOO true
#if FOO
diff --git a/clang/test/Sema/c++-keyword-in-c.c b/clang/test/Sema/c++-keyword-in-c.c
index f417469441114..89b5edbabbd9c 100644
--- a/clang/test/Sema/c++-keyword-in-c.c
+++ b/clang/test/Sema/c++-keyword-in-c.c
@@ -200,10 +200,10 @@ int import;
int override;
int final;
-// We do not diagnose use of C++ keywords when used as a macro name because
-// that does not conflict with C++ (the macros will be replaced before the
-// keyword is seen by the parser).
-#define this 12
+// In C mode, we do not diagnose use of C++ keywords when used as a macro name
+// because that does not conflict with C++ (the macros will be replaced before
+// the keyword is seen by the parser).
+#define this 12 // cxx-warning {{keyword is hidden by macro definition}}
// FIXME: These tests are disabled for C++ because it causes a crash.
// See GH114815.
diff --git a/clang/test/SemaCUDA/noinline.cu b/clang/test/SemaCUDA/noinline.cu
index ce4dfe35ceaa8..e8e45c127eda2 100644
--- a/clang/test/SemaCUDA/noinline.cu
+++ b/clang/test/SemaCUDA/noinline.cu
@@ -13,7 +13,7 @@ __attribute__((__noinline__)) void fun3() { }
#define __noinline__ __attribute__((__noinline__))
__noinline__ void fun5() {}
-#undef __noinline__
+#undef __noinline__ // pedantic-warning {{keyword or identifier with special meaning is used as a macro name}}
#10 "cuda.h" 3 // pedantic-warning {{this style of line directive is a GNU extension}}
#define __noinline__ __attribute__((__noinline__))
__noinline__ void fun6() {}
diff --git a/clang/test/SemaCXX/abstract.cpp b/clang/test/SemaCXX/abstract.cpp
index 730d7e390f1d0..70c972261853c 100644
--- a/clang/test/SemaCXX/abstract.cpp
+++ b/clang/test/SemaCXX/abstract.cpp
@@ -4,6 +4,7 @@
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
#define __CONCAT1(__X, __Y) __X ## __Y
+// expected-warning at +1 {{keyword is hidden by macro definition}}
#define static_assert(__b, __m) \
typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
#endif
diff --git a/clang/test/SemaCXX/consteval-builtin.cpp b/clang/test/SemaCXX/consteval-builtin.cpp
index 3ba95b4dbd9b5..2bb0d43ac3557 100644
--- a/clang/test/SemaCXX/consteval-builtin.cpp
+++ b/clang/test/SemaCXX/consteval-builtin.cpp
@@ -26,7 +26,7 @@
// c-error at -4 {{does not have the constexpr builtin}}
#if __cplusplus < 201103L
-#define static_assert __extension__ _Static_assert
+#define static_assert __extension__ _Static_assert // c-warning {{keyword is hidden by macro definition}}
#define CONSTEXPR11
#else
#define CONSTEXPR11 constexpr
diff --git a/clang/test/SemaTemplate/instantiate-array.cpp b/clang/test/SemaTemplate/instantiate-array.cpp
index 41d1cfe138ab5..f317be4d22bac 100644
--- a/clang/test/SemaTemplate/instantiate-array.cpp
+++ b/clang/test/SemaTemplate/instantiate-array.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
-// expected-no-diagnostics
#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
#define __CONCAT1(__X, __Y) __X ## __Y
+// expected-warning at +1 {{keyword is hidden by macro definition}}
#define static_assert(__b, __m) \
typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
#endif
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 16ebeb1052b79..dfe2172ab2590 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -448,7 +448,19 @@ <h2 id="cxx26">C++2c implementation status</h2>
<tr>
<td>Preprocessing is never undefined</td>
<td><a href="https://wg21.link/P2843">P2843R3</a></td>
- <td class="none" align="center">No</td>
+ <td class="partial" align="center">
+ <details>
+ <summary>Clang 24 (Partial)</summary>
+ Error-by-default warning for #define keyword;
+ Pedantic warning for #undef keyword;
+ #line is covered by P4136R2;
+ For attributes, there has been no discussions - The conservative approach is to do nothing;
+ For define in macros, the discussion doesn't seem to have reached its course yet.
+
+ The changes in this paper may break some legacy code, so we have tried to minimize the breakage
+ while providing users with clear diagnostic information to avoid introducing new undefined behaviors.
+ </details>
+ </td>
</tr>
<!-- Kona, Fall 2025-->
<tr>
More information about the cfe-commits
mailing list