https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/218322

>From ac925ed27622ca13c93d09255044be33ce679744 Mon Sep 17 00:00:00 2001
From: yronglin <[email protected]>
Date: Sun, 23 Aug 2026 22:41:55 -0700
Subject: [PATCH 1/3] [C++26] Implement P2843R3 - Preprocessing is never
 undefined (define/undef keyword part)

Signed-off-by: yronglin <[email protected]>
---
 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@-1 {{keyword is hidden by macro definition}}
+// pedantic-warning@-2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error@-3 {{keyword is hidden by macro definition}}
+#undef for
+// pedantic-warning@-1 {{keyword or identifier with special meaning is used as 
a macro name}}
+// pedantic-errors-error@-2 {{keyword or identifier with special meaning is 
used as a macro name}}
+
+#define final 1
+// default-warning@-1 {{keyword is hidden by macro definition}}
+// pedantic-warning@-2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error@-3 {{keyword is hidden by macro definition}}
+#undef final
+// pedantic-warning@-1 {{keyword or identifier with special meaning is used as 
a macro name}}
+// pedantic-errors-error@-2 {{keyword or identifier with special meaning is 
used as a macro name}}
+
+#define override
+// default-warning@-1 {{keyword is hidden by macro definition}}
+// pedantic-warning@-2 {{keyword is hidden by macro definition}}
+// pedantic-errors-error@-3 {{keyword is hidden by macro definition}}
+#undef override
+// pedantic-warning@-1 {{keyword or identifier with special meaning is used as 
a macro name}}
+// pedantic-errors-error@-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@-1 {{keyword or identifier with special meaning is used as 
a macro name}}
+// pedantic-errors-error@-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@+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@-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@+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>

>From 60791dbe872a436e2be9b639f54234a1d790c3dc Mon Sep 17 00:00:00 2001
From: yronglin <[email protected]>
Date: Sun, 23 Aug 2026 23:10:55 -0700
Subject: [PATCH 2/3] Fix cwg3088

Signed-off-by: yronglin <[email protected]>
---
 clang/test/CXX/drs/cwg3088.cpp | 188 ++++++++++++++++-----------------
 1 file changed, 94 insertions(+), 94 deletions(-)

diff --git a/clang/test/CXX/drs/cwg3088.cpp b/clang/test/CXX/drs/cwg3088.cpp
index 39c02dd31fc6c..5dc5aaab70822 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 
-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
+// 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
 
 // 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.
@@ -16,317 +16,317 @@ namespace cwg3088 { // cwg3088: partial
 
 #define asm
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef asm
+#undef asm // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define asm()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define auto
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef auto
+#undef auto // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define auto()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define bool
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef bool
+#undef bool // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define bool()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define break
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef break
+#undef break // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define break()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define case
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef case
+#undef case // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define case()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define catch
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef catch
+#undef catch // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define catch()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define char
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef char
+#undef char // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define char()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define class
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef class
+#undef class // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define class()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define const
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef const
+#undef const // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define const()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define const_cast
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef const_cast
+#undef const_cast // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define const_cast()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define continue
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef continue
+#undef continue // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define continue()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define default
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef default
+#undef default // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define default()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define delete
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef delete
+#undef delete // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define delete()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define do
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef do
+#undef do // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define do()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define double
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef double
+#undef double // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define double()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define dynamic_cast
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef dynamic_cast
+#undef dynamic_cast // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define dynamic_cast()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define else
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef else
+#undef else // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define else()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define enum
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef enum
+#undef enum // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define enum()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define explicit
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef explicit
+#undef explicit // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define explicit()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define export
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef export
+#undef export // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define export()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define extern
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef extern
+#undef extern // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define extern()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define false
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef false
+#undef false // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define false()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define float
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef float
+#undef float // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define float()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define for
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef for
+#undef for // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define for()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define friend
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef friend
+#undef friend // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define friend()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define goto
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef goto
+#undef goto // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define goto()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define if
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef if
+#undef if // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define if()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define inline
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef inline
+#undef inline // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define inline()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define int
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef int
+#undef int // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define int()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define long
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef long
+#undef long // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define long()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define mutable
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef mutable
+#undef mutable // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define mutable()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define namespace
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef namespace
+#undef namespace // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define namespace()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define new
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef new
+#undef new // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define new()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define operator
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef operator
+#undef operator // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define operator()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define private
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef private
+#undef private // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define private()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define protected
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef protected
+#undef protected // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define protected()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define public
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef public
+#undef public // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define public()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define register
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef register
+#undef register // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define register()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define reinterpret_cast
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef reinterpret_cast
+#undef reinterpret_cast // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define reinterpret_cast()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define return
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef return
+#undef return // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define return()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define short
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef short
+#undef short // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define short()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define signed
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef signed
+#undef signed // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define signed()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define sizeof
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef sizeof
+#undef sizeof // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define sizeof()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define static
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef static
+#undef static // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define static()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define static_cast
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef static_cast
+#undef static_cast // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define static_cast()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define struct
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef struct
+#undef struct // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define struct()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define switch
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef switch
+#undef switch // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define switch()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define template
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef template
+#undef template // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define template()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define this
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef this
+#undef this // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define this()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define throw
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef throw
+#undef throw // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define throw()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define true
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef true
+#undef true // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define true()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define try
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef try
+#undef try // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define try()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define typedef
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef typedef
+#undef typedef // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define typedef()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define typeid
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef typeid
+#undef typeid // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define typeid()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define typename
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef typename
+#undef typename // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define typename()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define union
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef union
+#undef union // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define union()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define unsigned
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef unsigned
+#undef unsigned // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define unsigned()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define using
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef using
+#undef using // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define using()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define virtual
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef virtual
+#undef virtual // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define virtual()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define void
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef void
+#undef void // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define void()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define volatile
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef volatile
+#undef volatile // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define volatile()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define wchar_t
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef wchar_t
+#undef wchar_t // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define wchar_t()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 #define while
 // expected-error@-1 {{keyword is hidden by macro definition}}
-#undef while
+#undef while // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define while()
 // expected-error@-1 {{keyword is hidden by macro definition}}
 
@@ -404,52 +404,52 @@ namespace cwg3088 { // cwg3088: partial
 
 #define alignas
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef alignas
+#undef alignas // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define alignas()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define alignof
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef alignof
+#undef alignof // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define alignof()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define char16_t
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef char16_t
+#undef char16_t // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define char16_t()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define char32_t
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef char32_t
+#undef char32_t // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define char32_t()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define constexpr
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef constexpr
+#undef constexpr // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define constexpr()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define decltype
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef decltype
+#undef decltype // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define decltype()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define noexcept
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef noexcept
+#undef noexcept // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define noexcept()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define nullptr
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef nullptr
+#undef nullptr // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define nullptr()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define static_assert
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef static_assert
+#undef static_assert // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define static_assert()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define thread_local
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef thread_local
+#undef thread_local // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define thread_local()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 
@@ -457,12 +457,12 @@ namespace cwg3088 { // cwg3088: partial
 
 #define final
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef final
+#undef final // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define final()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 #define override
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
-#undef override
+#undef override // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define override()
 // since-cxx11-error@-1 {{keyword is hidden by macro definition}}
 
@@ -511,42 +511,42 @@ namespace cwg3088 { // cwg3088: partial
 
 #define char8_t
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef char8_t
+#undef char8_t // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define char8_t()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define concept
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef concept
+#undef concept // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define concept()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define consteval
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef consteval
+#undef consteval // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define consteval()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define constinit
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef constinit
+#undef constinit // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define constinit()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define co_await
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef co_await
+#undef co_await // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define co_await()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define co_return
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef co_return
+#undef co_return // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define co_return()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define co_yield
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef co_yield
+#undef co_yield // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define co_yield
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 #define requires
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
-#undef requires
+#undef requires // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define requires()
 // since-cxx20-error@-1 {{keyword is hidden by macro definition}}
 
@@ -595,7 +595,7 @@ namespace cwg3088 { // cwg3088: partial
 
 #define contract_assert
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef contract_assert
+#undef contract_assert // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define contract_assert()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 
@@ -603,12 +603,12 @@ namespace cwg3088 { // cwg3088: partial
 
 #define post
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef post
+#undef post // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define post()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define pre
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef pre
+#undef pre // expected-error {{keyword or identifier with special meaning is 
used as a macro name}}
 #define pre()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 
@@ -616,7 +616,7 @@ namespace cwg3088 { // cwg3088: partial
 
 #define indeterminate
 // FIXME-since-cxx26-error@-1 {{attribute is hidden by macro definition}}
-#undef indeterminate
+#undef indeterminate // expected-error {{keyword or identifier with special 
meaning is used as a macro name}}
 #define indeterminate()
 // FIXME-since-cxx26-error@-1 {{attribute is hidden by macro definition}}
 #endif

>From ac4f135ca025a43741d4b63376f3c77f7f11ac98 Mon Sep 17 00:00:00 2001
From: yronglin <[email protected]>
Date: Mon, 24 Aug 2026 03:33:40 -0700
Subject: [PATCH 3/3] Add import and other special meaning keyword

Signed-off-by: yronglin <[email protected]>
---
 clang/lib/Lex/PPDirectives.cpp | 15 ++++++++++-----
 clang/test/CXX/drs/cwg3088.cpp |  4 ++--
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 5bca4f4ce6578..33c187c86533b 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -105,7 +105,7 @@ SourceRange Preprocessor::DiscardUntilEndOfDirective(
 enum MacroDiag {
   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,
+  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
@@ -217,9 +217,14 @@ static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, 
IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
   StringRef Text = II->getName();
   if (II->isKeyword(Lang))
-    return MD_KeywordUnDef;
-  if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))
-    return MD_KeywordUnDef;
+    return MD_KeywordUndef;
+
+  // [lex.name]/p2: Identifiers with special meaning
+  if ((Lang.CPlusPlus26 && (Text == "post" || Text == "pre")) ||
+      (Lang.CPlusPlus20 && (Text == "module" || Text == "import")) ||
+      (Lang.CPlusPlus11 && (Text == "override" || Text == "final")))
+    return MD_KeywordUndef;
+
   if (isReservedInAllContexts(II->isReserved(Lang)))
     return MD_ReservedMacro;
   if (isReservedCXXAttributeName(PP, II))
@@ -418,7 +423,7 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, 
MacroUse isDefineUndef,
       if (ShadowFlag)
         *ShadowFlag = true;
     }
-    if (D == MD_KeywordUnDef)
+    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);
diff --git a/clang/test/CXX/drs/cwg3088.cpp b/clang/test/CXX/drs/cwg3088.cpp
index 5dc5aaab70822..aeb7d6e11dd72 100644
--- a/clang/test/CXX/drs/cwg3088.cpp
+++ b/clang/test/CXX/drs/cwg3088.cpp
@@ -554,12 +554,12 @@ namespace cwg3088 { // cwg3088: partial
 
 #define import
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef import
+#undef import // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define import()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 #define module
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
-#undef module
+#undef module // expected-error {{keyword or identifier with special meaning 
is used as a macro name}}
 #define module()
 // FIXME-error@-1 {{keyword is hidden by macro definition}}
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to