aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-09-01 22:33:06 +0200
committerJakub Jelinek <jakub@redhat.com>2021-09-01 22:33:06 +0200
commitc4d6dcacfca1b804504515496e6d9de176d7f51e (patch)
tree712611d7a176373d8b0299a25eaf0a7f4e542bce /gcc
parent852fdc23a20d07087b5908b57ae7725f435732d5 (diff)
downloadgcc-c4d6dcacfca1b804504515496e6d9de176d7f51e.zip
gcc-c4d6dcacfca1b804504515496e6d9de176d7f51e.tar.gz
gcc-c4d6dcacfca1b804504515496e6d9de176d7f51e.tar.bz2
libcpp: Implement C++23 P1949R7 - C++ Identifier Syntax using Unicode Standard Annex 31
The following patch implements the P1949R7 - C++ Identifier Syntax using Unicode Standard Annex 31 paper. We already allow UTF-8 characters in the source, so that part is already implemented, so IMHO all we need to do is pedwarn instead of just warn for the (default) -Wnormalize=nfc (or for -Wnormalize={id,nkfc}) if the character is not in NFC and to use the unicode XID_Start and XID_Continue derived code properties to find out what characters are allowed (the standard actually adds U+005F to XID_Start, but we are handling the ASCII compatible characters differently already and they aren't allowed in UCNs in identifiers). Instead of hardcoding the large tables in ucnid.tab, this patch makes makeucnid.c read them from the Unicode tables (13.0.0 version at this point). For non-pedantic mode, we accept as 2nd+ char in identifiers a union of valid characters in all supported modes, but for the 1st char it was actually pedantically requiring that it is not any of the characters that may not appear in the currently chosen standard as the first character. This patch changes it such that also what is allowed at the start of an identifier is a union of characters valid at the start of an identifier in any of the pedantic modes. 2021-09-01 Jakub Jelinek <jakub@redhat.com> PR c++/100977 libcpp/ * include/cpplib.h (struct cpp_options): Add cxx23_identifiers. * charset.c (CXX23, NXX23): New enumerators. (CID, NFC, NKC, CTX): Renumber. (ucn_valid_in_identifier): Implement P1949R7 - use CXX23 and NXX23 flags for cxx23_identifiers. For start character in non-pedantic mode, allow characters that are allowed as start characters in any of the supported language modes, rather than disallowing characters allowed only as non-start characters in current mode but for characters from other language modes allowing them even if they are never allowed at start. * init.c (struct lang_flags): Add cxx23_identifiers. (lang_defaults): Add cxx23_identifiers column. (cpp_set_lang): Initialize CPP_OPTION (pfile, cxx23_identifiers). * lex.c (warn_about_normalization): If cxx23_identifiers, use cpp_pedwarning_with_line instead of cpp_warning_with_line for "is not in NFC" diagnostics. * makeucnid.c: Adjust usage comment. (CXX23, NXX23): New enumerators. (all_languages): Add CXX23. (not_NFC, not_NFKC, maybe_not_NFC): Renumber. (read_derivedcore): New function. (write_table): Print also CXX23 and NXX23 columns. (main): Require 5 arguments instead of 4, call read_derivedcore. * ucnid.h: Regenerated using Unicode 13.0.0 files. gcc/testsuite/ * g++.dg/cpp23/normalize1.C: New test. * g++.dg/cpp23/normalize2.C: New test. * g++.dg/cpp23/normalize3.C: New test. * g++.dg/cpp23/normalize4.C: New test. * g++.dg/cpp23/normalize5.C: New test. * g++.dg/cpp23/normalize6.C: New test. * g++.dg/cpp23/normalize7.C: New test. * g++.dg/cpp23/ucnid-1-utf8.C: New test. * g++.dg/cpp23/ucnid-2-utf8.C: New test. * gcc.dg/cpp/ucnid-4.c: Don't expect "not valid at the start of an identifier" errors. * gcc.dg/cpp/ucnid-4-utf8.c: Likewise. * gcc.dg/cpp/ucnid-5-utf8.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize1.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize2.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize3.C80
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize4.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize5.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize6.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp23/normalize7.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ucnid-1-utf8.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ucnid-2-utf8.C18
-rw-r--r--gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/ucnid-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c17
12 files changed, 423 insertions, 4 deletions
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize1.C b/gcc/testsuite/g++.dg/cpp23/normalize1.C
new file mode 100644
index 0000000..8357ed3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize1.C
@@ -0,0 +1,66 @@
+// { dg-do preprocess { target { c++11 && { ! c++23 } } } }
+// { dg-options "" }
+
+\u00AA
+\u00B7
+\u0F43 // { dg-warning "not in NFC" }
+a\u05B8\u05B9\u05B9\u05BBb
+ a\u05BB\u05B9\u05B8\u05B9b // { dg-warning "not in NFC" }
+\u09CB
+\u09C7\u09BE // { dg-warning "not in NFC" }
+\u0B4B
+\u0B47\u0B3E // { dg-warning "not in NFC" }
+\u0BCA
+\u0BC6\u0BBE // { dg-warning "not in NFC" }
+\u0BCB
+\u0BC7\u0BBE // { dg-warning "not in NFC" }
+\u0CCA
+\u0CC6\u0CC2 // { dg-warning "not in NFC" }
+\u0D4A
+\u0D46\u0D3E // { dg-warning "not in NFC" }
+\u0D4B
+\u0D47\u0D3E // { dg-warning "not in NFC" }
+
+K
+\u212A // { dg-warning "not in NFC" }
+
+\u03AC
+\u1F71 // { dg-warning "not in NFC" }
+
+\uAC00
+\u1100\u1161 // { dg-warning "not in NFC" }
+\uAC01
+\u1100\u1161\u11A8 // { dg-warning "not in NFC" }
+\uAC00\u11A8 // { dg-warning "not in NFC" }
+
+གྷ // { dg-warning "not in NFC" }
+aָֹֹֻb
+ aָֹֹֻb // { dg-warning "not in NFC" }
+ো
+ো // { dg-warning "not in NFC" }
+ୋ
+ୋ // { dg-warning "not in NFC" }
+ொ
+ொ // { dg-warning "not in NFC" }
+ோ
+ோ // { dg-warning "not in NFC" }
+ೊ
+ೊ // { dg-warning "not in NFC" }
+ൊ
+ൊ // { dg-warning "not in NFC" }
+ോ
+ോ // { dg-warning "not in NFC" }
+
+K
+K // { dg-warning "not in NFC" }
+
+ά // { dg-warning "not in NFC" }
+
+가
+가 // { dg-warning "not in NFC" }
+각
+각 // { dg-warning "not in NFC" }
+각 // { dg-warning "not in NFC" }
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize2.C b/gcc/testsuite/g++.dg/cpp23/normalize2.C
new file mode 100644
index 0000000..ad14e64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize2.C
@@ -0,0 +1,66 @@
+// { dg-do preprocess { target { c++23 } } }
+// { dg-options "" }
+
+\u00AA
+\u00B7
+\u0F43 // { dg-warning "not in NFC" }
+a\u05B8\u05B9\u05B9\u05BBb
+ a\u05BB\u05B9\u05B8\u05B9b // { dg-warning "not in NFC" }
+\u09CB
+\u09C7\u09BE // { dg-warning "not in NFC" }
+\u0B4B
+\u0B47\u0B3E // { dg-warning "not in NFC" }
+\u0BCA
+\u0BC6\u0BBE // { dg-warning "not in NFC" }
+\u0BCB
+\u0BC7\u0BBE // { dg-warning "not in NFC" }
+\u0CCA
+\u0CC6\u0CC2 // { dg-warning "not in NFC" }
+\u0D4A
+\u0D46\u0D3E // { dg-warning "not in NFC" }
+\u0D4B
+\u0D47\u0D3E // { dg-warning "not in NFC" }
+
+K
+\u212A // { dg-warning "not in NFC" }
+
+\u03AC
+\u1F71 // { dg-warning "not in NFC" }
+
+\uAC00
+\u1100\u1161 // { dg-warning "not in NFC" }
+\uAC01
+\u1100\u1161\u11A8 // { dg-warning "not in NFC" }
+\uAC00\u11A8 // { dg-warning "not in NFC" }
+
+གྷ // { dg-warning "not in NFC" }
+aָֹֹֻb
+ aָֹֹֻb // { dg-warning "not in NFC" }
+ো
+ো // { dg-warning "not in NFC" }
+ୋ
+ୋ // { dg-warning "not in NFC" }
+ொ
+ொ // { dg-warning "not in NFC" }
+ோ
+ோ // { dg-warning "not in NFC" }
+ೊ
+ೊ // { dg-warning "not in NFC" }
+ൊ
+ൊ // { dg-warning "not in NFC" }
+ോ
+ോ // { dg-warning "not in NFC" }
+
+K
+K // { dg-warning "not in NFC" }
+
+ά // { dg-warning "not in NFC" }
+
+가
+가 // { dg-warning "not in NFC" }
+각
+각 // { dg-warning "not in NFC" }
+각 // { dg-warning "not in NFC" }
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize3.C b/gcc/testsuite/g++.dg/cpp23/normalize3.C
new file mode 100644
index 0000000..bf4bb3a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize3.C
@@ -0,0 +1,80 @@
+// { dg-do preprocess { target { c++23 } } }
+// { dg-options "-pedantic-errors" }
+
+\u00AA
+\u00B7 // { dg-error "is not valid at the start of an identifier" }
+\u0F43 // { dg-error "not in NFC" }
+a\u05B8\u05B9\u05B9\u05BBb
+ a\u05BB\u05B9\u05B8\u05B9b // { dg-error "not in NFC" }
+\u09CB // { dg-error "is not valid at the start of an identifier" }
+\u09C7\u09BE // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0B4B // { dg-error "is not valid at the start of an identifier" }
+\u0B47\u0B3E // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0BCA // { dg-error "is not valid at the start of an identifier" }
+\u0BC6\u0BBE // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0BCB // { dg-error "is not valid at the start of an identifier" }
+\u0BC7\u0BBE // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0CCA // { dg-error "is not valid at the start of an identifier" }
+\u0CC6\u0CC2 // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0D4A // { dg-error "is not valid at the start of an identifier" }
+\u0D46\u0D3E // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+\u0D4B // { dg-error "is not valid at the start of an identifier" }
+\u0D47\u0D3E // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+
+K
+\u212A // { dg-error "not in NFC" }
+
+\u03AC
+\u1F71 // { dg-error "not in NFC" }
+
+\uAC00
+\u1100\u1161 // { dg-error "not in NFC" }
+\uAC01
+\u1100\u1161\u11A8 // { dg-error "not in NFC" }
+\uAC00\u11A8 // { dg-error "not in NFC" }
+
+· // { dg-error "is not valid at the start of an identifier" }
+གྷ // { dg-error "not in NFC" }
+aָֹֹֻb
+ aָֹֹֻb // { dg-error "not in NFC" }
+ো // { dg-error "is not valid at the start of an identifier" }
+ো // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ୋ // { dg-error "is not valid at the start of an identifier" }
+ୋ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ொ // { dg-error "is not valid at the start of an identifier" }
+ொ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ோ // { dg-error "is not valid at the start of an identifier" }
+ோ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ೊ // { dg-error "is not valid at the start of an identifier" }
+ೊ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ൊ // { dg-error "is not valid at the start of an identifier" }
+ൊ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+ോ // { dg-error "is not valid at the start of an identifier" }
+ോ // { dg-error "not in NFC" }
+ // { dg-error "is not valid at the start of an identifier" "" { target *-*-* } .-1 }
+
+K
+K // { dg-error "not in NFC" }
+
+ά // { dg-error "not in NFC" }
+
+가
+가 // { dg-error "not in NFC" }
+각
+각 // { dg-error "not in NFC" }
+각 // { dg-error "not in NFC" }
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize4.C b/gcc/testsuite/g++.dg/cpp23/normalize4.C
new file mode 100644
index 0000000..9f83cd7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize4.C
@@ -0,0 +1,66 @@
+// { dg-do preprocess { target { c++23 } } }
+// { dg-options "" }
+
+\u00AA
+x\u00B7
+\u0F43 // { dg-warning "not in NFC" }
+a\u05B8\u05B9\u05B9\u05BBb
+ a\u05BB\u05B9\u05B8\u05B9b // { dg-warning "not in NFC" }
+x\u09CB
+x\u09C7\u09BE // { dg-warning "not in NFC" }
+x\u0B4B
+x\u0B47\u0B3E // { dg-warning "not in NFC" }
+x\u0BCA
+x\u0BC6\u0BBE // { dg-warning "not in NFC" }
+x\u0BCB
+x\u0BC7\u0BBE // { dg-warning "not in NFC" }
+x\u0CCA
+x\u0CC6\u0CC2 // { dg-warning "not in NFC" }
+x\u0D4A
+x\u0D46\u0D3E // { dg-warning "not in NFC" }
+x\u0D4B
+x\u0D47\u0D3E // { dg-warning "not in NFC" }
+
+K
+\u212A // { dg-warning "not in NFC" }
+
+\u03AC
+\u1F71 // { dg-warning "not in NFC" }
+
+\uAC00
+\u1100\u1161 // { dg-warning "not in NFC" }
+\uAC01
+\u1100\u1161\u11A8 // { dg-warning "not in NFC" }
+\uAC00\u11A8 // { dg-warning "not in NFC" }
+
+x·
+གྷ // { dg-warning "not in NFC" }
+aָֹֹֻb
+ aָֹֹֻb // { dg-warning "not in NFC" }
+xো
+xো // { dg-warning "not in NFC" }
+xୋ
+xୋ // { dg-warning "not in NFC" }
+xொ
+xொ // { dg-warning "not in NFC" }
+xோ
+xோ // { dg-warning "not in NFC" }
+xೊ
+xೊ // { dg-warning "not in NFC" }
+xൊ
+xൊ // { dg-warning "not in NFC" }
+xോ
+xോ // { dg-warning "not in NFC" }
+
+K
+K // { dg-warning "not in NFC" }
+
+ά // { dg-warning "not in NFC" }
+
+가
+가 // { dg-warning "not in NFC" }
+각
+각 // { dg-warning "not in NFC" }
+각 // { dg-warning "not in NFC" }
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize5.C b/gcc/testsuite/g++.dg/cpp23/normalize5.C
new file mode 100644
index 0000000..afe339a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize5.C
@@ -0,0 +1,66 @@
+// { dg-do preprocess { target { c++23 } } }
+// { dg-options "-pedantic-errors" }
+
+\u00AA
+x\u00B7
+\u0F43 // { dg-error "not in NFC" }
+a\u05B8\u05B9\u05B9\u05BBb
+ a\u05BB\u05B9\u05B8\u05B9b // { dg-error "not in NFC" }
+x\u09CB
+x\u09C7\u09BE // { dg-error "not in NFC" }
+x\u0B4B
+x\u0B47\u0B3E // { dg-error "not in NFC" }
+x\u0BCA
+x\u0BC6\u0BBE // { dg-error "not in NFC" }
+x\u0BCB
+x\u0BC7\u0BBE // { dg-error "not in NFC" }
+x\u0CCA
+x\u0CC6\u0CC2 // { dg-error "not in NFC" }
+x\u0D4A
+x\u0D46\u0D3E // { dg-error "not in NFC" }
+x\u0D4B
+x\u0D47\u0D3E // { dg-error "not in NFC" }
+
+K
+\u212A // { dg-error "not in NFC" }
+
+\u03AC
+\u1F71 // { dg-error "not in NFC" }
+
+\uAC00
+\u1100\u1161 // { dg-error "not in NFC" }
+\uAC01
+\u1100\u1161\u11A8 // { dg-error "not in NFC" }
+\uAC00\u11A8 // { dg-error "not in NFC" }
+
+x·
+གྷ // { dg-error "not in NFC" }
+aָֹֹֻb
+ aָֹֹֻb // { dg-error "not in NFC" }
+xো
+xো // { dg-error "not in NFC" }
+xୋ
+xୋ // { dg-error "not in NFC" }
+xொ
+xொ // { dg-error "not in NFC" }
+xோ
+xோ // { dg-error "not in NFC" }
+xೊ
+xೊ // { dg-error "not in NFC" }
+xൊ
+xൊ // { dg-error "not in NFC" }
+xോ
+xോ // { dg-error "not in NFC" }
+
+K
+K // { dg-error "not in NFC" }
+
+ά // { dg-error "not in NFC" }
+
+가
+가 // { dg-error "not in NFC" }
+각
+각 // { dg-error "not in NFC" }
+각 // { dg-error "not in NFC" }
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize6.C b/gcc/testsuite/g++.dg/cpp23/normalize6.C
new file mode 100644
index 0000000..4c2b141
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize6.C
@@ -0,0 +1,10 @@
+// P1949R7
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+constexpr int À = 1; // U+00C0
+constexpr int À = 2; // U+0041 U+0300 { dg-warning "is not in NFC" }
+constexpr int gv1 = \u00c0;
+constexpr int gv2 = A\u0300; // { dg-warning "is not in NFC" }
+static_assert(gv1 == 1, "");
+static_assert(gv2 == 2, "");
diff --git a/gcc/testsuite/g++.dg/cpp23/normalize7.C b/gcc/testsuite/g++.dg/cpp23/normalize7.C
new file mode 100644
index 0000000..f639d65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/normalize7.C
@@ -0,0 +1,12 @@
+// P1949R7
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic-errors" }
+
+constexpr int À = 1; // U+00C0
+constexpr int À = 2; // U+0041 U+0300 { dg-warning "is not in NFC" "" { target { ! c++23 } } }
+// { dg-error "is not in NFC" "" { target c++23 } .-1 }
+constexpr int gv1 = \u00c0;
+constexpr int gv2 = A\u0300; // { dg-warning "is not in NFC" "" { target { ! c++23 } } }
+// { dg-error "is not in NFC" "" { target c++23 } .-1 }
+static_assert(gv1 == 1, "");
+static_assert(gv2 == 2, "");
diff --git a/gcc/testsuite/g++.dg/cpp23/ucnid-1-utf8.C b/gcc/testsuite/g++.dg/cpp23/ucnid-1-utf8.C
new file mode 100644
index 0000000..61acc82
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ucnid-1-utf8.C
@@ -0,0 +1,18 @@
+// P1949R7
+// { dg-do compile }
+// { dg-options "" }
+
+bool 👷 = true;
+bool 👷‍♀ = false; // { dg-error "is not valid in an identifier" }
+int ⏰ = 0; // { dg-error "is not valid in an identifier" }
+int 🕐 = 0;
+int ☠ = 0; // { dg-error "is not valid in an identifier" }
+int 💀 = 0;
+int ✋ = 0; // { dg-error "is not valid in an identifier" }
+int 👊 = 0;
+int ✈ = 0; // { dg-error "is not valid in an identifier" }
+int 🚀 = 0;
+int ☹ = 0; // { dg-error "is not valid in an identifier" }
+int 😀 = 0;
+struct E {};
+class 💩 : public E {};
diff --git a/gcc/testsuite/g++.dg/cpp23/ucnid-2-utf8.C b/gcc/testsuite/g++.dg/cpp23/ucnid-2-utf8.C
new file mode 100644
index 0000000..6c8aa6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ucnid-2-utf8.C
@@ -0,0 +1,18 @@
+// P1949R7
+// { dg-do compile }
+// { dg-options "-pedantic-errors" }
+
+bool 👷 = true; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+bool 👷‍♀ = false; // { dg-error "is not valid in an identifier" }
+int ⏰ = 0; // { dg-error "is not valid in an identifier" }
+int 🕐 = 0; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+int ☠ = 0; // { dg-error "is not valid in an identifier" }
+int 💀 = 0; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+int ✋ = 0; // { dg-error "is not valid in an identifier" }
+int 👊 = 0; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+int ✈ = 0; // { dg-error "is not valid in an identifier" }
+int 🚀 = 0; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+int ☹ = 0; // { dg-error "is not valid in an identifier" }
+int 😀 = 0; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
+struct E {};
+class 💩 : public E {}; // { dg-error "is not valid in an identifier" "" { target { c++98_only || c++23 } } }
diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c b/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c
index ccc7a1e..0a527ef 100644
--- a/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c
+++ b/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c
@@ -9,9 +9,9 @@
Ö
΄
-٩ /* { dg-error "not valid at the start of an identifier" } */
-๙ /* { dg-error "not valid at the start of an identifier" } */
+๙
A๙
diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-4.c b/gcc/testsuite/gcc.dg/cpp/ucnid-4.c
index e41a3f5..dceed66 100644
--- a/gcc/testsuite/gcc.dg/cpp/ucnid-4.c
+++ b/gcc/testsuite/gcc.dg/cpp/ucnid-4.c
@@ -9,9 +9,9 @@
\u00D6
\u0384
-\u0669 /* { dg-error "not valid at the start of an identifier" } */
+\u0669
A\u0669
0\u00BA
0\u0669
-\u0E59 /* { dg-error "not valid at the start of an identifier" } */
+\u0E59
A\u0E59
diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c b/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c
new file mode 100644
index 0000000..79767b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c
@@ -0,0 +1,17 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+« /* not a preprocessing error because we lex it into its own token */
+¶ /* not a preprocessing error because we lex it into its own token */
+΄ /* not a preprocessing error because we lex it into its own token */
+
+٩ /* { dg-error "not valid at the start of an identifier" } */
+A٩
+0º
+0٩
+๙ /* { dg-error "not valid at the start of an identifier" } */
+A๙