https://gcc.gnu.org/g:d3ba71bb14c57c3b12ca433c99ba42b6421aa353

commit r16-9279-gd3ba71bb14c57c3b12ca433c99ba42b6421aa353
Author: Jakub Jelinek <[email protected]>
Date:   Wed Jun 10 22:41:48 2026 +0200

    c++: Fix up __PRETTY_FUNCTION__ initializer translation [PR91155]
    
    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.
    
    2026-06-10  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.
    
    Reviewed-by: Jason Merrill <[email protected]>
    (cherry picked from commit 6791a54109c33394a9ab5ef603cec5e8ecbd9953)

Diff:
---
 gcc/cp/decl.cc                         | 13 +++++--------
 gcc/testsuite/g++.dg/torture/pr91155.C | 13 +++++++------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 923a0f4ef7de..9d6b34badf51 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -5901,18 +5901,15 @@ cp_make_fname_decl (location_t loc, tree id, int 
type_dep)
       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);
diff --git a/gcc/testsuite/g++.dg/torture/pr91155.C 
b/gcc/testsuite/g++.dg/torture/pr91155.C
index 04e4f7ab41b8..507f939f790d 100644
--- a/gcc/testsuite/g++.dg/torture/pr91155.C
+++ b/gcc/testsuite/g++.dg/torture/pr91155.C
@@ -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;
 }

Reply via email to