Hi!

In r16-4399 I've added reencoding of __PRETTY_FUNCTION__ initializer
from the source character set to execution character set.
I've used cpp_translate_string for that, which unfortunately interprets
some escape sequences in the string, and as this testcase shows, those
can appear in __PRETTY_FUNCTION__ and in this case made an old bug reappear.
What didn't help is that the PR91155 testcase had a test for the exact
values but with abort calls commented out and was dg-do compile only by
default, so it actually didn't test anything.
Since then for -freflection purposes cpp_translate_string has been added,
and that doesn't interpret anything, only changes encoding (if needed).

So, the following patch just uses that new function.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2026-06-06  Jakub Jelinek  <[email protected]>

        PR c++/91155
        * decl.cc (cp_make_fname_decl): Use cpp_translate_string instead of
        cpp_interpret_string, don't prefix name strname.text with " and suffix
        with " and NUL.

        * g++.dg/torture/pr91155.C: Change into dg-do run test, actually test
        the strings are the same.

--- gcc/cp/decl.cc.jj   2026-06-02 08:15:04.000000000 +0200
+++ gcc/cp/decl.cc      2026-06-05 16:40:37.543159065 +0200
@@ -5906,18 +5906,15 @@ cp_make_fname_decl (location_t loc, tree
       if (!release_name)
        {
          cpp_string cstr = { 0, 0 }, strname;
-         size_t len = strlen (name) + 3; /* Two for '"'s.  One for NULL.  */
-         char *namep = XNEWVEC (char, len);
-         snprintf (namep, len, "\"%s\"", name);
-         strname.text = (unsigned char *) namep;
-         strname.len = len - 1;
-         if (cpp_interpret_string (parse_in, &strname, 1, &cstr, CPP_STRING))
+         strname.text
+           = const_cast <unsigned char *> ((const unsigned char *) name);
+         strname.len = strlen (name) + 1;
+         if (cpp_translate_string (parse_in, &strname, &cstr, CPP_STRING,
+                                   false))
            {
              name = (const char *) cstr.text;
              release_name = true;
            }
-
-         XDELETEVEC (namep);
        }
 
       size_t length = strlen (name);
--- gcc/testsuite/g++.dg/torture/pr91155.C.jj   2026-03-27 10:17:16.268295916 
+0100
+++ gcc/testsuite/g++.dg/torture/pr91155.C      2026-06-05 16:55:58.600318183 
+0200
@@ -1,4 +1,5 @@
-/* PR c++/91155.  */
+// PR c++/91155
+// { dg-do run }
 
 template< char C > struct dummy {};
 
@@ -10,9 +11,9 @@ template< typename T > const char *test(
 
 int main()
 {
-    if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\000\'>]", 
test< dummy< '\0' > > ()) != 0)
-    {};//      __builtin_abort ();
-    if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\\'\'>]", 
test< dummy< '\'' > > ()) != 0)
-    {};//      __builtin_abort ();
-    return 0;
+  if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\000\'>]", 
test< dummy< '\0' > > ()) != 0)
+    __builtin_abort ();
+  if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\\'\'>]", test< 
dummy< '\'' > > ()) != 0)
+    __builtin_abort ();
+  return 0;
 }

        Jakub

Reply via email to