[gcc r17-3021] Fix up cpp_check_xid_property (used by rust)

Jakub Jelinek via Gcc-cvs <[email protected]> Thu, 6 Aug 2026 09:47:19 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:393a84e17375c8545a36e758067bac8dc7200367

commit r17-3021-g393a84e17375c8545a36e758067bac8dc7200367
Author: Jakub Jelinek <[email protected]>
Date:   Thu Aug 6 11:45:28 2026 +0200

    Fix up cpp_check_xid_property (used by rust)
    
    I believe cpp_check_xid_property (function added to libcpp for the Rust
    FE) is incorrect.
    The bits are documented
      /* Valid in a C++23 identifier?  */
      CXX23 = 32,
      /* Valid in a C++23 identifier, but not as the first character?  */
      NXX23 = 64,
    So, characters which have both the Unicode XID_Start and XID_Continue
    derived properties have just CXX23 bit set, and characters which
    have just XID_Continue derived property and not XID_Start have
    CXX23|NXX23 bits set.
    So, I believe the function (except for the ASCII fast path which is correct)
    incorrectly returns CPP_XID_START | CPP_XID_CONTINUE for any characters
    which have XID_Continue derived property, and only ever returns just
    CPP_XID_CONTINUE in the ASCII [0-9_] cases.
    
    The following untested patch should fix that, I guess it would be nice to
    have a testcase, pick some character in XID_Continue and not in XID_Start,
    random choice e.g. SUNDANESE CONSONANT SIGN PASANGAN WA, and check if
    it can be used in the second+ character of identifier (probably it can and
    should continue to do so) and as the first character of identifier
    (likely incorrectly accepted right now).
    
    2026-08-06  Jakub Jelinek  <[email protected]>
    
            * charset.cc (cpp_check_xid_property): Return
            CPP_XID_START | CPP_XID_CONTINUE only if CXX23 bit is set and NXX23
            is not.  If both are set, return CPP_XID_CONTINUE.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 libcpp/charset.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcpp/charset.cc b/libcpp/charset.cc
index 9e83c95fd03b..1616e0a27bab 100644
--- a/libcpp/charset.cc
+++ b/libcpp/charset.cc
@@ -1370,9 +1370,9 @@ cpp_check_xid_property (cppchar_t c)
 
   if (flags & NONC)
     return 0;
-  if (flags & CXX23)
+  if ((flags & (CXX23 | NXX23)) == CXX23)
     return CPP_XID_START | CPP_XID_CONTINUE;
-  if (flags & NXX23)
+  if ((flags & (CXX23 | NXX23)) == (CXX23 | NXX23))
     return CPP_XID_CONTINUE;
   return 0;
 }