aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-08-07 08:51:00 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2025-08-07 08:51:00 +0200
commit2c5bd8e9fb16584cdd1d090b9a5a63dd9140b61b (patch)
tree2be451690698a928f8ed895a966f53511b625827 /gcc
parent64859dc6e2948616439b500b5d9ffb2635b45ae8 (diff)
downloadgcc-2c5bd8e9fb16584cdd1d090b9a5a63dd9140b61b.zip
gcc-2c5bd8e9fb16584cdd1d090b9a5a63dd9140b61b.tar.gz
gcc-2c5bd8e9fb16584cdd1d090b9a5a63dd9140b61b.tar.bz2
c++: Add testcase for CWG2576 [PR120778]
Another part of the C++26 P2843R3, this time in https://eel.is/c++draft/cpp.include#7 changing former (compile time) undefined behavior to IFNDR. With IFNDR we wouldn't have to test anything I guess, but this still adds the cases from the 3.4 section of the paper plus related tests. The paper wonders about implementation divergence between most compilers and gcc in the case of glueing tokens together with <> around from multiple macros, GCC doesn't add CPP_PADDING macros in that case (and even if it would, it would ignore them through get_token_no_padding). But I think this behavior is allowed by https://eel.is/c++draft/cpp.include#7.sentence-3 and changing it now after 25+ years of such behavior might break real-world stuff, especially making it really hard to construct the <> includes from some name and adding < and > from some other macro around that. We handle #define A <cstd def> #include A like clang++ and try to open 'cstd def' file. But not adding spaces for all the padding means handling even stuff where nothing else can help, while for cstd def coming from different macros one can use token pasting to combine them together, e.g. < and following identifier or identifier followed by . or . followed by identifier or identifier followed by > can't be pasted together. 2025-08-07 Jakub Jelinek <jakub@redhat.com> PR preprocessor/120778 * g++.dg/DRs/dr2576.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2576.C47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/DRs/dr2576.C b/gcc/testsuite/g++.dg/DRs/dr2576.C
new file mode 100644
index 0000000..ed53a08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2576.C
@@ -0,0 +1,47 @@
+// DR 2576 - Undefined behavior with macro-expanded #include directives
+// { dg-do preprocess }
+// { dg-options "-pedantic-errors" }
+
+#define A <cstddef>
+#include A
+#define B "cstddef"
+#include B
+#define C(x) #x
+#define D(x) C(x)
+#include D(cstddef)
+#include "cstddef" "" // { dg-error "extra tokens at end of '#include' directive" }
+#include "cstddef"".h" // { dg-error "extra tokens at end of '#include' directive" }
+#include // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" }
+#include E // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" }
+#include <cstddef
+ // { dg-error "missing terminating '>' character" "" { target *-*-* } .-1 }
+#include "cstddef
+ // { dg-error "missing terminating \" character" "" { target *-*-* } .-1 }
+ // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" "" { target *-*-* } .-2 }
+#define F cstddef
+#include F // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" }
+// There is implementation divergence on the following cases (G H through M N)
+// between e.g. GCC and clang++. clang++ fails on trying to include ' cstddef'
+// and 'cstd def' and 'stddef .h' and 'cstddef ' headers.
+// https://eel.is/c++draft/cpp.include#7.sentence-3 makes the whitespace
+// handling implementation defined and the way GCC handles it can allow
+// certain use cases which aren't otherwise possible. One can still
+// insert spaces into the <> filenames if it is from the same macro.
+#define G <
+#define H cstddef>
+#include G H
+#define I <cstd
+#define J def>
+#include I J
+#define K <stddef
+#define L .h>
+#include K L
+#define M <cstddef
+#define N >
+#include M N
+#define O <cstddef> <cstddef>
+#include O // { dg-error "extra tokens at end of '#include' directive" }
+#define P "cstddef" ""
+#include P // { dg-error "extra tokens at end of '#include' directive" }
+#define Q "cstddef"".h"
+#include Q // { dg-error "extra tokens at end of '#include' directive" }