diff options
author | msebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-09 23:12:10 +0000 |
---|---|---|
committer | msebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-09 23:12:10 +0000 |
commit | 911ea34a73cce91d41f814ea791f2edbac8c27b4 (patch) | |
tree | f486cc289cc2e46c1ccb063b50662b02da10b20b /gcc | |
parent | acbc95ac1c85f2a0057a1d9dab3405377bb463d3 (diff) | |
download | gcc-911ea34a73cce91d41f814ea791f2edbac8c27b4.tar.gz |
PR c/77520 - wrong value for extended ASCII characters in -Wformat message
PR c/77521 - %qc format directive should quote non-printable characters
gcc/c-family/ChangeLog:
PR c/77520
PR c/77521
* c-format.c (argument_parser::find_format_char_info): Use %qc
format directive unconditionally.
gcc/ChangeLog:
PR c/77520
PR c/77521
* pretty-print.c (pp_quoted_string): New function.
(pp_format): Call it for %c and %s directives.
gcc/testsuite/ChangeLog:
PR c/77520
PR c/77521
* gcc.dg/pr77520.c: New test.
* gcc.dg/pr77521.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240059 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-family/c-format.c | 20 | ||||
-rw-r--r-- | gcc/pretty-print.c | 58 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr77520.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr77521.c | 8 |
7 files changed, 100 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb8ad6e5a4b..68921618973 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-09-09 Martin Sebor <msebor@redhat.com> + + PR c/77520 + PR c/77521 + * pretty-print.c (pp_quoted_string): New function. + (pp_format): Call it for %c and %s directives. + 2016-09-10 Bernd Edlinger <bernd.edlinger@hotmail.de> * doc/tm.texi.in (INITIAL_FRAME_POINTER_OFFSET): Remove. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index ba892487aa8..9a78b7aaac8 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2016-09-09 Martin Sebor <msebor@redhat.com> + + PR c/77520 + PR c/77521 + * c-format.c (argument_parser::find_format_char_info): Use %qc + format directive unconditionally. + 2016-09-09 Jason Merrill <jason@redhat.com> Implement C++17 new of over-aligned types. diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 09d514ec594..0c173409520 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -2355,20 +2355,12 @@ argument_parser::find_format_char_info (char format_char) ++fci; if (fci->format_chars == 0) { - if (ISGRAPH (format_char)) - format_warning_at_char (format_string_loc, format_string_cst, - format_chars - orig_format_chars, - OPT_Wformat_, - "unknown conversion type character" - " %qc in format", - format_char); - else - format_warning_at_char (format_string_loc, format_string_cst, - format_chars - orig_format_chars, - OPT_Wformat_, - "unknown conversion type character" - " 0x%x in format", - format_char); + format_warning_at_char (format_string_loc, format_string_cst, + format_chars - orig_format_chars, + OPT_Wformat_, + "unknown conversion type character" + " %qc in format", + format_char); return NULL; } diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c index 325263efd6a..a39815ea511 100644 --- a/gcc/pretty-print.c +++ b/gcc/pretty-print.c @@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see #include <iconv.h> #endif +static void pp_quoted_string (pretty_printer *, const char *, size_t = -1); + /* Overwrite the given location/range within this text_info's rich_location. For use e.g. when implementing "+" in client format decoders. */ @@ -555,8 +557,20 @@ pp_format (pretty_printer *pp, text_info *text) break; case 'c': - pp_character (pp, va_arg (*text->args_ptr, int)); - break; + { + /* When quoting, print alphanumeric, punctuation, and the space + character unchanged, and all others in hexadecimal with the + "\x" prefix. Otherwise print them all unchanged. */ + int chr = va_arg (*text->args_ptr, int); + if (ISPRINT (chr) || !quote) + pp_character (pp, chr); + else + { + const char str [2] = { chr, '\0' }; + pp_quoted_string (pp, str, 1); + } + break; + } case 'd': case 'i': @@ -577,7 +591,10 @@ pp_format (pretty_printer *pp, text_info *text) break; case 's': - pp_string (pp, va_arg (*text->args_ptr, const char *)); + if (quote) + pp_quoted_string (pp, va_arg (*text->args_ptr, const char *)); + else + pp_string (pp, va_arg (*text->args_ptr, const char *)); break; case 'p': @@ -939,6 +956,41 @@ pp_string (pretty_printer *pp, const char *str) pp_maybe_wrap_text (pp, str, str + strlen (str)); } +/* Append the leading N characters of STRING to the output area of + PRETTY-PRINTER, quoting in hexadecimal non-printable characters. + Setting N = -1 is as if N were set to strlen (STRING). The STRING + may be line-wrapped if in appropriate mode. */ +static void +pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */) +{ + gcc_checking_assert (str); + + const char *last = str; + const char *ps; + + /* Compute the length if not specified. */ + if (n == (size_t) -1) + n = strlen (str); + + for (ps = str; n; ++ps, --n) + { + if (ISPRINT (*ps)) + continue; + + if (last < ps) + pp_maybe_wrap_text (pp, last, ps - 1); + + /* Append the hexadecimal value of the character. Allocate a buffer + that's large enough for a 32-bit char plus the hex prefix. */ + char buf [11]; + int n = sprintf (buf, "\\x%02x", (unsigned char)*ps); + pp_maybe_wrap_text (pp, buf, buf + n); + last = ps + 1; + } + + pp_maybe_wrap_text (pp, last, ps); +} + /* Maybe print out a whitespace if needed. */ void diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 56ff8bc9ff9..3b934a03a90 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-09-09 Martin Sebor <msebor@redhat.com> + + PR c/77520 + PR c/77521 + * gcc.dg/pr77520.c: New test. + * gcc.dg/pr77521.c: New test. + 2016-09-09 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/77506 diff --git a/gcc/testsuite/gcc.dg/pr77520.c b/gcc/testsuite/gcc.dg/pr77520.c new file mode 100644 index 00000000000..b237639fb20 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr77520.c @@ -0,0 +1,10 @@ +/* PR c/77520 - wrong value for extended ASCII characters in -Wformat message + Verify that characters in the extended ASCII range are quoted and not + allowed to be printed raw. */ +/* { dg-do compile } */ +/* { dg-options "-Wformat" } */ + +void f (void) +{ + __builtin_printf ("%\x80"); /* { dg-warning "unknown conversion type character .\\\\x80. in format" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr77521.c b/gcc/testsuite/gcc.dg/pr77521.c new file mode 100644 index 00000000000..f6b1e3ed269 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr77521.c @@ -0,0 +1,8 @@ +/* PR c/77521 - %qc format directive should quote non-printable characters. + Verify that non-printable characters in assembly constraints are quoted + and not allowed to be printed raw. */ + +void f (int a, int b) +{ + __asm__ ("combine %2, %0" : "=r" (a) : "0" (a), "\n" (b)); /* { dg-error "invalid punctuation .\\\\x0a. in constraint" } */ +} |