aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-common.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/format-nonlit-3.c16
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2119c93..ab777ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+ * c-common.c (check_format_info): Warn for non-constant format
+ strings with strftime formats if -Wformat-nonliteral. Where the
+ format can convert arguments, if the format is not a string
+ literal and there are no arguments to the format, give a different
+ warning message from the general non-string-literal case.
+
+2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
* c-common.c (format_wanted_type): Add reading_from_flag.
(print_char_table): Mark %s and %S formats with flag "R".
(check_format_info_main): Set up reading_from_flag appropriately.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 7359b04..5e7666a 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2345,8 +2345,29 @@ check_format_info (status, info, params)
/* Functions taking a va_list normally pass a non-literal format
string. These functions typically are declared with
first_arg_num == 0, so avoid warning in those cases. */
- if (info->first_arg_num != 0 && warn_format_nonliteral)
- status_warning (status, "format not a string literal, argument types not checked");
+ if (!(format_types[info->format_type].flags & FMT_FLAG_ARG_CONVERT))
+ {
+ /* For strftime-like formats, warn for not checking the format
+ string; but there are no arguments to check. */
+ if (warn_format_nonliteral)
+ status_warning (status, "format not a string literal, format string not checked");
+ }
+ else if (info->first_arg_num != 0)
+ {
+ /* If there are no arguments for the format at all, we may have
+ printf (foo) which is likely to be a security hole. */
+ while (arg_num + 1 < info->first_arg_num)
+ {
+ if (params == 0)
+ break;
+ params = TREE_CHAIN (params);
+ ++arg_num;
+ }
+ if (params == 0 && warn_format_nonliteral)
+ status_warning (status, "format not a string literal and no format arguments");
+ else if (warn_format_nonliteral)
+ status_warning (status, "format not a string literal, argument types not checked");
+ }
}
/* If there were extra arguments to the format, normally warn. However,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 444f2d6..d597494 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+ * gcc.dg/format-nonlit-3.c: New test.
+
+2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
* gcc.dg/c90-printf-1.c: Add test for printf formats reading
through a null pointer.
diff --git a/gcc/testsuite/gcc.dg/format-nonlit-3.c b/gcc/testsuite/gcc.dg/format-nonlit-3.c
new file mode 100644
index 0000000..4423151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/format-nonlit-3.c
@@ -0,0 +1,16 @@
+/* Test for warnings for non-string-literal formats. Test for strftime formats. */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat -Wformat-nonliteral" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct tm;
+
+extern size_t strftime (char *, size_t, const char *, const struct tm *);
+
+void
+foo (char *s, size_t m, const struct tm *tp, char *fmt)
+{
+ strftime (s, m, fmt, tp); /* { dg-warning "format string" "non-literal" } */
+}