[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