This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for bug 15444
- From: "Joseph S. Myers" <jsm at polyomino dot org dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 15 May 2004 00:44:27 +0000 (UTC)
- Subject: Patch for bug 15444
Here is a patch for PR c/15444, requesting a more specific diagnostic
when formats use $ operand numbers after a format without such a
number has been used in the format string.
Bootstrapped with no regressions on i686-pc-linux-gnu. Applied to
mainline.
2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/15444
* c-format.c (avoid_dollar_number): New function.
(check_format_info_main): Call avoid_dollar_number when operand
numbers might occur but has_operand_number == 0.
2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/15444
* gcc.dg/format/xopen-1.c: Adjust expected message.
* gcc.dg/format/xopen-3.c: New test.
diff -rupN gcc.orig/c-format.c gcc/c-format.c
--- gcc.orig/c-format.c 2004-05-13 08:47:12.000000000 +0000
+++ gcc/c-format.c 2004-05-14 20:32:58.000000000 +0000
@@ -1023,6 +1023,7 @@ static void status_warning (int *, const
static void init_dollar_format_checking (int, tree);
static int maybe_read_dollar_number (int *, const char **, int,
tree, tree *, const format_kind_info *);
+static bool avoid_dollar_number (int *, const char *);
static void finish_dollar_format_checking (int *, format_check_results *, int);
static const format_flag_spec *get_flag_spec (const format_flag_spec *,
@@ -1304,6 +1305,26 @@ maybe_read_dollar_number (int *status, c
return argnum;
}
+/* Ensure that FORMAT does not start with a decimal number followed by
+ a $; give a diagnostic and return true if it does, false otherwise. */
+
+static bool
+avoid_dollar_number (int *status, const char *format)
+{
+ if (!ISDIGIT (*format))
+ return false;
+ while (ISDIGIT (*format))
+ format++;
+ if (*format == '$')
+ {
+ status_warning (status,
+ "$ operand number used after format"
+ " without operand number");
+ return true;
+ }
+ return false;
+}
+
/* Finish the checking for a format string that used $ operand number formats
instead of non-$ formats. We check for unused operands before used ones
@@ -1721,6 +1742,11 @@ check_format_info_main (int *status, for
main_arg_num = opnum + info->first_arg_num - 1;
}
}
+ else if (fki->flags & FMT_FLAG_USE_DOLLAR)
+ {
+ if (avoid_dollar_number (status, format_chars))
+ return;
+ }
/* Read any format flags, but do not yet validate them beyond removing
duplicates, since in general validation depends on the rest of
@@ -1780,6 +1806,11 @@ check_format_info_main (int *status, for
else
has_operand_number = 0;
}
+ else
+ {
+ if (avoid_dollar_number (status, format_chars))
+ return;
+ }
if (info->first_arg_num != 0)
{
if (params == 0)
@@ -1879,6 +1910,11 @@ check_format_info_main (int *status, for
else
has_operand_number = 0;
}
+ else
+ {
+ if (avoid_dollar_number (status, format_chars))
+ return;
+ }
if (info->first_arg_num != 0)
{
if (params == 0)
diff -rupN gcc.orig/testsuite/gcc.dg/format/xopen-1.c gcc/testsuite/gcc.dg/format/xopen-1.c
--- gcc.orig/testsuite/gcc.dg/format/xopen-1.c 2001-11-25 18:50:24.000000000 +0000
+++ gcc/testsuite/gcc.dg/format/xopen-1.c 2004-05-14 20:35:24.000000000 +0000
@@ -95,7 +95,7 @@ foo (int i, unsigned int u, wint_t lc, w
scanf ("%4$ld%7$ld%5$d%6$d%3$d%1$d%2$d", ip, ip, ip, lp, ip, ip, lp);
printf ("%1$d%d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
printf ("%%%1$d%%%2$d", i, i);
- printf ("%d%2$d", i); /* { dg-warning "type character" "mixing $ and non-$ formats" } */
+ printf ("%d%2$d", i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
printf ("%1$*d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
printf ("%*1$d", i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
scanf ("%1$d%d", ip, ip); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
diff -rupN gcc.orig/testsuite/gcc.dg/format/xopen-3.c gcc/testsuite/gcc.dg/format/xopen-3.c
--- gcc.orig/testsuite/gcc.dg/format/xopen-3.c 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/format/xopen-3.c 2004-05-14 20:39:01.000000000 +0000
@@ -0,0 +1,15 @@
+/* Test for warnings for $ operand numbers after ordinary formats.
+ Bug c/15444 from james-gcc-bugzilla-501qll3d at and dot org. */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat" } */
+
+#include "format.h"
+
+void
+foo (int i)
+{
+ printf ("%d%2$d", i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
+ printf ("%d%*1$d", i, i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
+ printf ("%d%.*1$d", i, i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
+}
--
Joseph S. Myers
jsm@polyomino.org.uk