PR c/15444
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 May 2004 00:44:02 +0000 (00:44 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 May 2004 00:44:02 +0000 (00:44 +0000)
* 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.

testsuite:
* gcc.dg/format/xopen-1.c: Adjust expected message.
* gcc.dg/format/xopen-3.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81871 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-format.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format/xopen-1.c
gcc/testsuite/gcc.dg/format/xopen-3.c [new file with mode: 0644]

index 01e0c66..2e9f6b9 100644 (file)
@@ -1,3 +1,10 @@
+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-14  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.md (all peephole2 patterns): Use predicates that validate
index 17ef68a..c4a6ece 100644 (file)
@@ -1023,6 +1023,7 @@ static void status_warning (int *, const char *, ...)
 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, const char **format,
   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, format_check_results *res,
              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, format_check_results *res,
                  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, format_check_results *res,
                  else
                    has_operand_number = 0;
                }
+             else
+               {
+                 if (avoid_dollar_number (status, format_chars))
+                   return;
+               }
              if (info->first_arg_num != 0)
                {
                  if (params == 0)
index 7e14671..d192d2f 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2004-05-14  Victor Leikehman  <lei@haifasphere.co.il>
 
        * gfortran.fortran-torture/execute/def_init_3.f90: New test.
index 934dcb1..1462a2c 100644 (file)
@@ -95,7 +95,7 @@ foo (int i, unsigned int u, wint_t lc, wchar_t *ls, int *ip, double d,
   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 --git a/gcc/testsuite/gcc.dg/format/xopen-3.c b/gcc/testsuite/gcc.dg/format/xopen-3.c
new file mode 100644 (file)
index 0000000..5f78d77
--- /dev/null
@@ -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" } */
+}