--- libcpp/charset.cc	2022-08-20 23:29:12.817996729 +0200
+++ libcpp/charset.cc	2022-08-25 10:34:16.652212078 +0200
@@ -1037,13 +1037,13 @@
 			     U+0F0A TIBETAN MARK BKA- SHOG YIG MGO
 			     U+0FD0 TIBETAN MARK BKA- SHOG GI MGO RGYAN
 			     U+0FD0 TIBETAN MARK BSKA- SHOG GI MGO RGYAN
-			     and makeuname2c.cc verifies this.
 			     Furthermore, prefixes of NR2 generated
 			     ranges all end with a hyphen, but the generated
 			     part is then followed by alpha-numeric.
 			     So, let's just assume that - at the end of
 			     key is always followed by alphanumeric and
-			     so should be omitted.  */
+			     so should be omitted.
+			     makeuname2c.cc verifies that this is true.  */
 			  ++q;
 			  continue;
 			}
@@ -1090,10 +1090,7 @@
 		      winner[i] = -1;
 		      for (j = start; j < end; j++)
 			{
-			  /* Actually strlen, but we know strlen () <= 3.  */
-			  for (this_len = 0; hangul_syllables[j][this_len];
-			       ++this_len)
-			    ;
+			  this_len = strlen (hangul_syllables[j]);
 			  if (len >= (size_t) this_len
 			      && this_len > max_len
 			      && memcmp (name, hangul_syllables[j],
@@ -1196,6 +1193,69 @@
   return -1;
 }
 
+/* Try to do a loose name lookup according to Unicode loose matching rule
+   UAX44-LM2.  First ignore medial hyphens, whitespace, underscore
+   characters and convert to upper case.  */
+
+static cppchar_t
+_cpp_uname2c_uax44_lm2 (const char *name, size_t len, char *canon_name)
+{
+  char name_after_uax44_lm2[uname2c_max_name_len];
+  char *q = name_after_uax44_lm2;
+  const char *p;
+
+  for (p = name; p < name + len; p++)
+    if (*p == '_' || *p == ' ')
+      continue;
+    else if (*p == '-' && p != name && ISALNUM (p[-1]) && ISALNUM (p[1]))
+      continue;
+    else if (q == name_after_uax44_lm2 + uname2c_max_name_len)
+      return -1;
+    else if (ISLOWER (*p))
+      *q++ = TOUPPER (*p);
+    else
+      *q++ = *p;
+
+  struct uname2c_data data;
+  data.canon_name = canon_name;
+  data.prev_char = ' ';
+  /* Hangul Jungseong O- E after UAX44-LM2 should be HANGULJUNGSEONGO-E
+     and so should match U+1180.  */
+  if (q - name_after_uax44_lm2 == sizeof ("HANGULJUNGSEONGO-E") - 1
+      && memcmp (name_after_uax44_lm2, "HANGULJUNGSEONGO-E",
+		 sizeof ("HANGULJUNGSEONGO-E") - 1) == 0)
+    {
+      name_after_uax44_lm2[sizeof ("HANGULJUNGSEONGO") - 1] = 'E';
+      --q;
+    }
+  cppchar_t result
+    = _cpp_uname2c (name_after_uax44_lm2, q - name_after_uax44_lm2,
+		    uname2c_tree, &data);
+
+  /* Unicode UAX44-LM2 exception:
+     U+116C HANGUL JUNGSEONG OE
+     U+1180 HANGUL JUNGSEONG O-E
+     We remove all medial hyphens when we shouldn't remote the U+1180 one.
+     The U+1180 entry sorts before U+116C lexicographilly, so we get U+1180
+     in both cases.  Thus, if result is U+1180, check if user's name doesn't
+     have a hyphen there and adjust.  */
+  if (result == 0x1180)
+    {
+      while (p[-1] == ' ' || p[-1] == '_')
+	--p;
+      gcc_assert (TOUPPER (p[-1]) == 'E');
+      --p;
+      while (p[-1] == ' ' || p[-1] == '_')
+	--p;
+      if (p[-1] != '-')
+	{
+	  result = 0x116c;
+	  memcpy (canon_name + sizeof ("HANGUL JUNGSEONG O") - 1, "E", 2);
+	}
+    }
+  return result;
+}
+
 
 /* Returns 1 if C is valid in an identifier, 2 if C is valid except at
    the start of an identifier, and 0 if C is not valid in an
@@ -1448,96 +1508,26 @@
 		{
 		  /* If the name is longer than maximum length of a Unicode
 		     name, it can't be strictly valid.  */
-		  if ((size_t) (str - name) > uname2c_max_name_len)
-		    strict = false;
-
-		  if (!strict)
+		  if ((size_t) (str - name) > uname2c_max_name_len || !strict)
 		    result = -1;
 		  else
 		    result = _cpp_uname2c ((const char *) name, str - name,
 					   uname2c_tree, NULL);
 		  if (result == (cppchar_t) -1)
 		    {
-		      char name_after_uax44_lm2[uname2c_max_name_len];
-
 		      cpp_error (pfile, CPP_DL_ERROR,
 				 "\\N{%.*s} is not a valid universal "
 				 "character", (int) (str - name), name);
 
 		      /* Try to do a loose name lookup according to
-			 Unicode loose matching rule UAX44-LM2.
-			 First ignore medial hyphens, whitespace, underscore
-			 characters and convert to upper case.  */
-		      char *q = name_after_uax44_lm2;
-		      const uchar *p;
-		      for (p = name; p < str; p++)
-			if (*p == '_' || *p == ' ')
-			  continue;
-			else if (*p == '-'
-				 && p != name
-				 && ISALNUM (p[-1])
-				 && ISALNUM (p[1]))
-			  continue;
-			else if (q == name_after_uax44_lm2 + uname2c_max_name_len)
-			  break;
-			else if (ISLOWER (*p))
-			  *q++ = TOUPPER (*p);
-			else
-			  *q++ = *p;
-		      if (p == str)
-			{
-			  char canon_name[uname2c_max_name_len + 1];
-			  struct uname2c_data data;
-			  data.canon_name = canon_name;
-			  data.prev_char = ' ';
-			  /* Hangul Jungseong O- E
-			     after UAX44-LM2 should be HANGULJUNGSEONGO-E
-			     and so should match U+1180.  */
-			  if (q - name_after_uax44_lm2
-			      == sizeof ("HANGULJUNGSEONGO-E") - 1
-			      && memcmp (name_after_uax44_lm2,
-					 "HANGULJUNGSEONGO-E",
-					 sizeof ("HANGULJUNGSEONGO-E")
-					 - 1) == 0)
-			    {
-			      name_after_uax44_lm2[sizeof ("HANGULJUNGSEONGO")
-						   - 1] = 'E';
-			      --q;
-			    }
-			  result = _cpp_uname2c (name_after_uax44_lm2,
-						 q - name_after_uax44_lm2,
-						 uname2c_tree, &data);
-			  /* Unicode UAX44-LM2 exception:
-			     U+116C HANGUL JUNGSEONG OE
-			     U+1180 HANGUL JUNGSEONG O-E
-			     We remove all medial hyphens when we shouldn't
-			     remote the U+1180 one.  The U+1180 entry sorts
-			     before U+116C lexicographilly, so we get U+1180
-			     in both cases.  Thus, if result is U+1180,
-			     check if user's name doesn't have a hyphen there
-			     and adjust.  */
-			  if (result == 0x1180)
-			    {
-			      while (p[-1] == ' ' || p[-1] == '_')
-				--p;
-			      gcc_assert (TOUPPER (p[-1]) == 'E');
-			      --p;
-			      while (p[-1] == ' ' || p[-1] == '_')
-				--p;
-			      if (p[-1] != '-')
-				{
-				  result = 0x116c;
-				  memcpy (canon_name
-					  + sizeof ("HANGUL JUNGSEONG O") - 1,
-					  "E", 2);
-				}
-			    }
-			  if (result != (cppchar_t) -1)
-			    cpp_error (pfile, CPP_DL_NOTE,
-				       "did you mean \\N{%s}?",
-				       canon_name);
-			}
-		      if (result == (cppchar_t) -1)
+			 Unicode loose matching rule UAX44-LM2.  */
+		      char canon_name[uname2c_max_name_len + 1];
+		      result = _cpp_uname2c_uax44_lm2 ((const char *) name,
+						       str - name, canon_name);
+		      if (result != (cppchar_t) -1)
+			cpp_error (pfile, CPP_DL_NOTE,
+				   "did you mean \\N{%s}?", canon_name);
+		      else
 			result = 0x40;
 		    }
 		}
