aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-05-01 18:51:15 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-05-01 18:51:15 +0000
commit2cc7d3a7da20bcfd854302b1f265c6551b8a3741 (patch)
tree6a4fbd7ff8617e1040301cc5459a55a9fbb6c517
parent41e2c1b0b4effb21729299c5dd7b3b2abd03d87b (diff)
downloadgcc-2cc7d3a7da20bcfd854302b1f265c6551b8a3741.zip
gcc-2cc7d3a7da20bcfd854302b1f265c6551b8a3741.tar.gz
gcc-2cc7d3a7da20bcfd854302b1f265c6551b8a3741.tar.bz2
-Wformat: fix nonsensical "wide character" message (PR c/84258)
gcc/c-family/ChangeLog: PR c/84258 * c-format.c (struct format_check_results): Add field "number_non_char". (check_format_info): Initialize it, and warn if encountered. (check_format_arg): Distinguish between wide char and everything else when detecting arrays of non-char. gcc/testsuite/ChangeLog: PR c/84258 * c-c++-common/Wformat-pr84258.c: New test. From-SVN: r259807
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c-format.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/Wformat-pr84258.c19
4 files changed, 49 insertions, 2 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index ab85a73..a6ae85f 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,12 @@
+2018-05-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/84258
+ * c-format.c (struct format_check_results): Add field
+ "number_non_char".
+ (check_format_info): Initialize it, and warn if encountered.
+ (check_format_arg): Distinguish between wide char and
+ everything else when detecting arrays of non-char.
+
2018-04-30 David Malcolm <dmalcolm@redhat.com>
* c-format.c (get_corrected_substring): Update for
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index ee7c33d..a0192dd 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -974,6 +974,8 @@ struct format_check_results
/* Number of leaves of the format argument that were wide string
literals. */
int number_wide;
+ /* Number of leaves of the format argument that are not array of "char". */
+ int number_non_char;
/* Number of leaves of the format argument that were empty strings. */
int number_empty;
/* Number of leaves of the format argument that were unterminated
@@ -1435,6 +1437,7 @@ check_format_info (function_format_info *info, tree params,
res.extra_arg_loc = UNKNOWN_LOCATION;
res.number_dollar_extra_args = 0;
res.number_wide = 0;
+ res.number_non_char = 0;
res.number_empty = 0;
res.number_unterminated = 0;
res.number_other = 0;
@@ -1511,6 +1514,10 @@ check_format_info (function_format_info *info, tree params,
if (res.number_wide > 0)
warning_at (loc, OPT_Wformat_, "format is a wide character string");
+ if (res.number_non_char > 0)
+ warning_at (loc, OPT_Wformat_,
+ "format string is not an array of type %qs", "char");
+
if (res.number_unterminated > 0)
warning_at (loc, OPT_Wformat_, "unterminated format string");
}
@@ -1656,9 +1663,16 @@ check_format_arg (void *ctx, tree format_tree,
res->number_non_literal++;
return;
}
- if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
+ tree underlying_type
+ = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree)));
+ if (underlying_type != char_type_node)
{
- res->number_wide++;
+ if (underlying_type == char16_type_node
+ || underlying_type == char32_type_node
+ || underlying_type == wchar_type_node)
+ res->number_wide++;
+ else
+ res->number_non_char++;
return;
}
format_chars = TREE_STRING_POINTER (format_tree);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cefe1ca..f5b94c6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/84258
+ * c-c++-common/Wformat-pr84258.c: New test.
+
2018-05-01 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR tree-optimization/82665
diff --git a/gcc/testsuite/c-c++-common/Wformat-pr84258.c b/gcc/testsuite/c-c++-common/Wformat-pr84258.c
new file mode 100644
index 0000000..d2870a8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wformat-pr84258.c
@@ -0,0 +1,19 @@
+/* { dg-options "-Wformat" } */
+
+int main (int argc, char **argv)
+{
+ char buf[10];
+
+ char c[] = "%i";
+ unsigned char uc[] = "%i";
+ const char cc[] = "%i";
+ const unsigned char cuc[] = "%i";
+
+ __builtin_sprintf(buf, (char *)c, 1);
+ __builtin_sprintf(buf, (char *)uc, 1);
+ __builtin_sprintf(buf, (char *)cc, 1);
+ __builtin_sprintf(buf, (char *)cuc, 1); /* { dg-warning "format string is not an array of type 'char'" } */
+ __builtin_sprintf(buf, (const char *)L"foo"); /* { dg-warning "format is a wide character string" } */
+
+ return 0;
+}