[clang] b104dab - Revert "[Clang] Implement P2843R3 - Preprocessing is never undefined" (#192532)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 16 14:05:38 PDT 2026


Author: gulfemsavrun
Date: 2026-04-16T21:05:32Z
New Revision: b104dab739ad6ad60ef0725d563d9a4ae640c5bf

URL: https://github.com/llvm/llvm-project/commit/b104dab739ad6ad60ef0725d563d9a4ae640c5bf
DIFF: https://github.com/llvm/llvm-project/commit/b104dab739ad6ad60ef0725d563d9a4ae640c5bf.diff

LOG: Revert "[Clang] Implement P2843R3 - Preprocessing is never undefined" (#192532)

Reverts llvm/llvm-project#192073 

Reason for revert: This change caused build failures on Windows when
compiling libcxx.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticLexKinds.td
    clang/lib/Lex/PPExpressions.cpp
    clang/test/Lexer/cxx-features.cpp
    clang/www/cxx_status.html

Removed: 
    clang/test/Preprocessor/p2843r3.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3dac89bdb8c37..161dcf65406ea 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -133,12 +133,6 @@ C++ Language Changes
 C++2c Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 
-- Partially implemented `P2843R3 <https://wg21.link/P2843R3>`_ Preprocessing is
-  never undefined. A macro expansion producing ``defined`` in a conditional
-  expression is now a hard error in C++26; other constructs the paper makes
-  ill-formed (notably embedding a directive within macro arguments) remain a
-  pedantic warning for now and will be promoted separately.
-
 C++23 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 

diff  --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index bda6cee95a4e7..2846db8320275 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -1060,8 +1060,6 @@ def warn_defined_in_object_type_macro : Warning<
 def warn_defined_in_function_type_macro : Extension<
   "macro expansion producing 'defined' has undefined behavior">,
   InGroup<ExpansionToDefined>;
-def err_defined_in_macro : Error<
-  "macro expansion producing 'defined' is not allowed">;
 
 let CategoryName = "Nullability Issue" in {
 

diff  --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 46eb66a2eac7e..887fd25ac318d 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -204,9 +204,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
     // in a 
diff erent way, and compilers seem to agree on how to behave here.
     // So warn by default on object-type macros, but only warn in -pedantic
     // mode on function-type macros.
-    if (PP.getLangOpts().CPlusPlus26)
-      PP.Diag(beginLoc, diag::err_defined_in_macro);
-    else if (IsFunctionTypeMacro)
+    if (IsFunctionTypeMacro)
       PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
     else
       PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);

diff  --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 446bb0ac76056..8eb9ea032879c 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -14,25 +14,21 @@
 
 // expected-no-diagnostics
 
-// An undefined feature-test macro evaluates to 0 in an #if expression, so
-// `__cpp_##macro != N` tests the feature is defined with the exact value N
-// when N is nonzero, and tests the feature is not defined (or is defined to 0,
-// which feature-test macros never are) when N is 0. Avoiding `defined` inside
-// a macro expansion is required for conformance with [cpp.cond].
+// FIXME using `defined` in a macro has undefined behavior.
 #if __cplusplus < 201103L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx98)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98)
 #elif __cplusplus < 201402L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx11)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx11 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx11)
 #elif __cplusplus < 201703L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx14)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx14 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx14)
 #elif __cplusplus < 202002L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx17)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx17 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx17)
 #elif __cplusplus < 202302L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx20)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx20 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx20)
 #elif __cplusplus == 202302L
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx23)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx23 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx23)
 #else
-#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (__cpp_##macro != cxx26)
+#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23, cxx26) (cxx26 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx26)
 #endif
 
 // --- C++26 features ---

diff  --git a/clang/test/Preprocessor/p2843r3.cpp b/clang/test/Preprocessor/p2843r3.cpp
deleted file mode 100644
index 58d06cb27a22f..0000000000000
--- a/clang/test/Preprocessor/p2843r3.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: %clang_cc1 -std=c++26 -pedantic -verify=cxx26,expected -Wno-invalid-pp-token %s
-// RUN: %clang_cc1 -std=c++23 -pedantic -verify=cxx23,expected -Wno-invalid-pp-token %s
-
-// P2843R3: Preprocessing is never undefined. The constructs this paper makes
-// ill-formed were previously undefined behavior; under C++26 Clang now
-// diagnoses them as errors, while retaining the pre-existing pedantic warning
-// in earlier language modes for compatibility.
-
-// [cpp.cond] A macro expansion that produces 'defined' in a conditional
-// expression. P2843R3 makes this ill-formed; promoted to a hard error in
-// C++26.
-#define DEFINED defined
-// cxx26-error at +2 {{macro expansion producing 'defined' is not allowed}}
-// cxx23-warning at +1 {{macro expansion producing 'defined' has undefined behavior}}
-#if DEFINED(bar)
-#endif
-
-// Malformed 'defined' operands are ill-formed in all modes.
-#if defined()      // expected-error {{macro name must be an identifier}}
-#endif
-#if defined(a b)   // expected-error {{missing ')' after 'defined'}} expected-note {{to match this '('}}
-#endif
-#if defined(a, b)  // expected-error {{missing ')' after 'defined'}} expected-note {{to match this '('}}
-#endif
-
-// [cpp.replace.general] A preprocessing directive inside the arguments of a
-// function-like macro invocation. Still only diagnosed as a pedantic warning;
-// promoting this to a hard error is tracked separately.
-#define FUNCTION_MACRO(...)
-FUNCTION_MACRO(
-    #if 0 // expected-warning {{embedding a directive within macro arguments has undefined behavior}}
-    #endif
-)
-
-// [cpp.concat] Concatenation that does not form a valid preprocessing token.
-#define CONCAT(A, B) A ## B
-CONCAT(=, >) // expected-error {{pasting formed '=>', an invalid preprocessing token}}
-// expected-error at -1 {{expected unqualified-id}}
-
-// [cpp.predefined] #undef of a reserved identifier / builtin macro.
-#undef defined  // expected-error {{'defined' cannot be used as a macro name}}
-#undef __DATE__ // expected-warning {{undefining builtin macro}}
-
-// [cpp.line] #line with a non-positive or out-of-range argument.
-#line 0          // expected-warning {{#line directive with zero argument is a GNU extension}}
-#line -1         // expected-error {{#line directive requires a positive integer argument}}
-#line 2147483647 // ok, largest value required to be accepted
-#line 2147483648 // expected-warning {{C requires #line number to be less than 2147483648, allowed as extension}}

diff  --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 5d6babd7a95c4..2c834b07f9a8f 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -330,15 +330,7 @@ <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="partial" align="center">
-     <details>
-       <summary>Partial</summary>
-       Clang diagnoses macro expansions producing <tt>defined</tt> in
-       conditional expressions in C++26, but embedded directives in macro
-       arguments and other constructs made ill-formed by this paper are not
-       yet fully implemented.
-     </details>
-   </td>
+   <td class="none" align="center">No</td>
  </tr>
  <!-- Kona, Fall 2025-->
  <tr>


        


More information about the cfe-commits mailing list