On 8/6/25 8:17 AM, Jakub Jelinek wrote:
Hi!
From the paper it isn't clear what caused the decision changes, not to drop
the "the token defined is generated as a result of this replacement process or"
part and make [cpp.cond]/10 violations IFNDR rather than ill-formed (the
latter maybe so that the extension to handle e.g. !A(A) below etc. can be
accepted).
Anyway, because that case hasn't been dropped and we pedwarn on it already,
and diagnose everything else the way it should, the following patch just
adds testcase for it.
Tested on x86_64-linux and i686-linux, ok for trunk?
OK.
2025-08-06 Jakub Jelinek <ja...@redhat.com>
PR preprocessor/120778
* g++.dg/DRs/dr2575.C: New test.
--- gcc/testsuite/g++.dg/DRs/dr2575.C.jj 2025-08-06 13:47:20.345720010
+0200
+++ gcc/testsuite/g++.dg/DRs/dr2575.C 2025-08-06 14:08:56.196505122 +0200
@@ -0,0 +1,51 @@
+// DR 2575 - Undefined behavior when macro-replacing "defined" operator
+// { dg-do preprocess }
+// { dg-options "-pedantic-errors" }
+
+#define A defined
+#if !A(A) // { dg-error "this use of 'defined' may not be
portable" }
+#error
+#endif
+#if A(B) // { dg-error "this use of 'defined' may not be
portable" }
+#error
+#endif
+#if !A A // { dg-error "this use of 'defined' may not be
portable" }
+#error
+#endif
+#if A B // { dg-error "this use of 'defined' may not be
portable" }
+#error
+#endif
+#if defined A + B
+#else
+#error
+#endif
+#if defined +B // { dg-error "operator 'defined' requires an
identifier" }
+#endif // { dg-error "missing binary operator before token 'B'"
"" { target *-*-* } .-1 }
+#if defined 1 // { dg-error "operator 'defined' requires an
identifier" }
+#endif
+#if defined // { dg-error "operator 'defined' requires an
identifier" }
+#endif
+#if defined (A + B) // { dg-error "missing '\\\)' after 'defined'" }
+#endif // { dg-error "missing binary operator before token 'B'"
"" { target *-*-* } .-1 }
+#if defined (+B) // { dg-error "operator 'defined' requires an
identifier" }
+#endif // { dg-error "missing binary operator before token 'B'"
"" { target *-*-* } .-1 }
+#if defined (1) // { dg-error "operator 'defined' requires an
identifier" }
+#endif // { dg-error "missing '\\\(' in expression" "" {
target *-*-* } .-1 }
+#if defined () // { dg-error "operator 'defined' requires an
identifier" }
+#endif
+#if defined A, B // { dg-error "comma operator in operand of #if" }
+#endif
+#if defined (A), B // { dg-error "comma operator in operand of #if" }
+#endif
+#if (defined A), B // { dg-error "comma operator in operand of #if" }
+#endif
+#if defined (A, B) // { dg-error "missing '\\\)' after 'defined'" }
+#endif // { dg-error "missing binary operator before token 'B'"
"" { target *-*-* } .-1 }
+#if defined (A) + B
+#else
+#error
+#endif
+#if (defined A) + B
+#else
+#error
+#endif
Jakub