While working on the -Wformat-length pass I noticed that in some diagnostics that make use of the %qc and %qs directives GCC prints non-printable characters raw. For example, it might print a newline, corrupting the diagnostic stream (bug 77521). Some other diagnostics that try to avoid this problem by using a directive such as %x when the character is not printable might use the sign-extended value of the character, printing a very large hexadecimal value (bug 77520). The attached patch changes the pretty printer to detect non-printable characters in %qc and %qs directives (but not %c or %s) and print those in hexadecimal (via "\\x%02x"). Martin PS I used hexadecimal based on what c-format.c does but now that I checked more carefully how %qE formats string literals I see it uses octal. I think hexadecimal is preferable because it avoids ambiguity but I'm open to changing it to octal if there's a strong preference for it. Incidentally, %qE too suffers from bug 77520 (see below). The patch doesn't try to fix that. $ cat z.C && gcc z.C constexpr int i = "ABC\x7f_\x80XYZ"; z.C:1:19: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive] constexpr int i = "ABC\x7f_\x80XYZ"; ^~~~~~~~~~~~~~~~~ z.C:1:19: error: ‘(int)((const char*)"ABC\177_\37777777600XYZ")’ is not a constant expression