OSDN Git Service

gcc:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Nov 2010 09:42:58 +0000 (09:42 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Nov 2010 09:42:58 +0000 (09:42 +0000)
2010-11-13  Paolo Bonzini  <bonzini@gnu.org>

* c-format.c (enum format_specifier_kind, kind_descriptions): New.
(struct format_wanted_type): Replace field "name" with "kind", add
"format_start" and "format_length".
(check_format_info_main): Fill in new fields.  Fill in
FORMAT_WANTED_TYPES even for missing arguments.  Move checks
after the final NUL outside the while loop.  Do not include
width and precision modifiers in the format_start/format_length
of the main format.
(check_format_types): Remove FORMAT_START and FORMAT_LENGTH
arguments.  Compute WANTED_TYPE first so that format_type_warning
can be called for missing arguments.  Adjust calls to
format_type_warning.
(format_type_warning): Fetch as much information as possible
from format_wanted_type.  Adjust printing now that every
warning has a "descr", as well as for missing argument warnings
and to include % sign for format specifiers.

testsuite:
2010-11-13  Paolo Bonzini  <bonzini@gnu.org>

* gcc.dg/format/few-1.c: New test.
* gcc.dg/format/asm_fprintf-1.c: Adjust.
* gcc.dg/format/c90-scanf-1.c: Adjust.
* gcc.dg/format/cmn-err-1.c: Adjust.
* gcc.dg/format/dfp-printf-1.c: Adjust.
* gcc.dg/format/dfp-scanf-1.c: Adjust.
* gcc.dg/format/gcc_diag-1.c: Adjust.
* gcc.dg/format/ms_unnamed-1.c: Adjust.
* gcc.dg/format/strfmon-1.c: Adjust.
* gcc.dg/format/unnamed-1.c: Adjust.
* gcc.dg/format/xopen-2.c: Adjust.
* g++.dg/ext/builtin4.C: Adjust.
* g++.dg/ext/builtin5.C: Adjust.

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

18 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/c-family/c-format.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/builtin4.C
gcc/testsuite/g++.dg/ext/builtin5.C
gcc/testsuite/gcc.dg/format/asm_fprintf-1.c
gcc/testsuite/gcc.dg/format/c90-printf-1.c
gcc/testsuite/gcc.dg/format/c90-scanf-1.c
gcc/testsuite/gcc.dg/format/cmn-err-1.c
gcc/testsuite/gcc.dg/format/dfp-printf-1.c
gcc/testsuite/gcc.dg/format/dfp-scanf-1.c
gcc/testsuite/gcc.dg/format/few-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/format/gcc_diag-1.c
gcc/testsuite/gcc.dg/format/ms_unnamed-1.c
gcc/testsuite/gcc.dg/format/strfmon-1.c
gcc/testsuite/gcc.dg/format/unnamed-1.c
gcc/testsuite/gcc.dg/format/xopen-2.c

index 9280996..44035e3 100644 (file)
@@ -1,3 +1,22 @@
+2010-11-13  Paolo Bonzini  <bonzini@gnu.org>
+
+       * c-format.c (enum format_specifier_kind, kind_descriptions): New.
+       (struct format_wanted_type): Replace field "name" with "kind", add
+       "format_start" and "format_length".
+       (check_format_info_main): Fill in new fields.  Fill in
+       FORMAT_WANTED_TYPES even for missing arguments.  Move checks
+       after the final NUL outside the while loop.  Do not include
+       width and precision modifiers in the format_start/format_length
+       of the main format.
+       (check_format_types): Remove FORMAT_START and FORMAT_LENGTH
+       arguments.  Compute WANTED_TYPE first so that format_type_warning
+       can be called for missing arguments.  Adjust calls to
+       format_type_warning.
+       (format_type_warning): Fetch as much information as possible
+       from format_wanted_type.  Adjust printing now that every
+       warning has a "descr", as well as for missing argument warnings
+       and to include % sign for format specifiers.
+
 2010-11-12  Alexander Monakov  <amonakov@ispras.ru>
 
        PR rtl-optimization/46204
index ce71b41..a43f434 100644 (file)
@@ -3689,7 +3689,7 @@ s-constrs-h: $(MD_DEPS) build/genpreds$(build_exeext)
        $(STAMP) s-constrs-h
 
 target-hooks-def.h: s-target-hooks-def-h; @true
-tm.texi: s-tm-texi; @true
+tm.texi: s-tm-texi
 
 s-target-hooks-def-h: build/genhooks$(build_exeext)
        $(RUN_GEN) build/genhooks$(build_exeext) > tmp-target-hooks-def.h
@@ -3942,7 +3942,9 @@ $(genprog:%=build/gen%$(build_exeext)): build/gen%$(build_exeext): build/gen%.o
        +$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
            $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
 
-# Generated source files for gengtype.
+# Generated source files for gengtype.  Prepend inclusion of
+# bconfig.h because AIX requires _LARGE_FILES to be defined before
+# any system header is included.
 gengtype-lex.c : gengtype-lex.l
        -$(FLEX) $(FLEXFLAGS) -o$@ $< && { \
          echo '#include "bconfig.h"' > $@.tmp; \
index a64717a..1ca181b 100644 (file)
@@ -356,6 +356,20 @@ decode_format_attr (tree args, function_format_info *info, int validated_p)
                                       ? (warn_long_long ? STD_C99 : STD_C89) \
                                       : (VER)))
 
+/* Enum describing the kind of specifiers present in the format and
+   requiring an argument.  */
+enum format_specifier_kind {
+  CF_KIND_FORMAT,
+  CF_KIND_FIELD_WIDTH,
+  CF_KIND_FIELD_PRECISION
+};
+
+static const char *kind_descriptions[] = {
+  N_("format"),
+  N_("field width specifier"),
+  N_("field precision specifier")
+};
+
 /* Structure describing details of a type expected in format checking,
    and the type to check against it.  */
 typedef struct format_wanted_type
@@ -377,11 +391,13 @@ typedef struct format_wanted_type
   /* Whether the argument, dereferenced once, is read from and so
      must not be a NULL pointer.  */
   int reading_from_flag;
-  /* If warnings should be of the form "field precision should have
-     type 'int'", the name to use (in this case "field precision"),
-     otherwise NULL, for "format expects type 'long'" type
-     messages.  */
-  const char *name;
+  /* The kind of specifier that this type is used for.  */
+  enum format_specifier_kind kind;
+  /* The starting character of the specifier.  This never includes the
+     initial percent sign.  */
+  const char *format_start;
+  /* The length of the specifier.  */
+  int format_length;
   /* The actual parameter to check against the wanted type.  */
   tree param;
   /* The argument number of that parameter.  */
@@ -957,9 +973,8 @@ static void finish_dollar_format_checking (format_check_results *, int);
 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
                                              int, const char *);
 
-static void check_format_types (format_wanted_type *, const char *, int);
-static void format_type_warning (const char *, const char *, int, tree,
-                                int, const char *, tree, int);
+static void check_format_types (format_wanted_type *);
+static void format_type_warning (format_wanted_type *, tree, tree);
 
 /* Decode a format type from a string, returning the type, or
    format_type_error if not valid, in which case the caller should print an
@@ -1619,7 +1634,7 @@ check_format_info_main (format_check_results *res,
 
   init_dollar_format_checking (info->first_arg_num, first_fillin_param);
 
-  while (1)
+  while (*format_chars != 0)
     {
       int i;
       int suppressed = FALSE;
@@ -1643,21 +1658,8 @@ check_format_info_main (format_check_results *res,
       char flag_chars[256];
       int alloc_flag = 0;
       int scalar_identity_flag = 0;
-      const char *format_start = format_chars;
-      if (*format_chars == 0)
-       {
-         if (format_chars - orig_format_chars != format_length)
-           warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format");
-         if (info->first_arg_num != 0 && params != 0
-             && has_operand_number <= 0)
-           {
-             res->number_other--;
-             res->number_extra_args++;
-           }
-         if (has_operand_number > 0)
-           finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
-         return;
-       }
+      const char *format_start;
+
       if (*format_chars++ != '%')
        continue;
       if (*format_chars == 0)
@@ -1762,16 +1764,16 @@ check_format_info_main (format_check_results *res,
              if (info->first_arg_num != 0)
                {
                  if (params == 0)
-                   {
-                     warning (OPT_Wformat, "too few arguments for format");
-                     return;
-                   }
-                 cur_param = TREE_VALUE (params);
-                 if (has_operand_number <= 0)
-                   {
-                     params = TREE_CHAIN (params);
-                     ++arg_num;
-                   }
+                    cur_param = NULL;
+                  else
+                    {
+                      cur_param = TREE_VALUE (params);
+                      if (has_operand_number <= 0)
+                        {
+                          params = TREE_CHAIN (params);
+                          ++arg_num;
+                        }
+                    }
                  width_wanted_type.wanted_type = *fki->width_type;
                  width_wanted_type.wanted_type_name = NULL;
                  width_wanted_type.pointer_count = 0;
@@ -1779,7 +1781,9 @@ check_format_info_main (format_check_results *res,
                  width_wanted_type.scalar_identity_flag = 0;
                  width_wanted_type.writing_in_flag = 0;
                  width_wanted_type.reading_from_flag = 0;
-                 width_wanted_type.name = _("field width");
+                  width_wanted_type.kind = CF_KIND_FIELD_WIDTH;
+                 width_wanted_type.format_start = format_chars - 1;
+                 width_wanted_type.format_length = 1;
                  width_wanted_type.param = cur_param;
                  width_wanted_type.arg_num = arg_num;
                  width_wanted_type.next = NULL;
@@ -1865,16 +1869,16 @@ check_format_info_main (format_check_results *res,
              if (info->first_arg_num != 0)
                {
                  if (params == 0)
-                   {
-                     warning (OPT_Wformat, "too few arguments for format");
-                     return;
-                   }
-                 cur_param = TREE_VALUE (params);
-                 if (has_operand_number <= 0)
-                   {
-                     params = TREE_CHAIN (params);
-                     ++arg_num;
-                   }
+                    cur_param = NULL;
+                  else
+                    {
+                      cur_param = TREE_VALUE (params);
+                      if (has_operand_number <= 0)
+                        {
+                          params = TREE_CHAIN (params);
+                          ++arg_num;
+                        }
+                    }
                  precision_wanted_type.wanted_type = *fki->precision_type;
                  precision_wanted_type.wanted_type_name = NULL;
                  precision_wanted_type.pointer_count = 0;
@@ -1882,8 +1886,10 @@ check_format_info_main (format_check_results *res,
                  precision_wanted_type.scalar_identity_flag = 0;
                  precision_wanted_type.writing_in_flag = 0;
                  precision_wanted_type.reading_from_flag = 0;
-                 precision_wanted_type.name = _("field precision");
+                  precision_wanted_type.kind = CF_KIND_FIELD_PRECISION;
                  precision_wanted_type.param = cur_param;
+                 precision_wanted_type.format_start = format_chars - 2;
+                 precision_wanted_type.format_length = 2;
                  precision_wanted_type.arg_num = arg_num;
                  precision_wanted_type.next = NULL;
                  if (last_wanted_type != 0)
@@ -1903,6 +1909,7 @@ check_format_info_main (format_check_results *res,
            }
        }
 
+      format_start = format_chars;
       if (fki->alloc_char && fki->alloc_char == *format_chars)
        {
          i = strlen (flag_chars);
@@ -2163,12 +2170,8 @@ check_format_info_main (format_check_results *res,
              /* Heuristic: skip one argument when an invalid length/type
                 combination is encountered.  */
              arg_num++;
-             if (params == 0)
-               {
-                 warning (OPT_Wformat, "too few arguments for format");
-                 return;
-               }
-             params = TREE_CHAIN (params);
+             if (params != 0)
+                params = TREE_CHAIN (params);
              continue;
            }
          else if (pedantic
@@ -2229,13 +2232,12 @@ check_format_info_main (format_check_results *res,
          while (fci)
            {
              if (params == 0)
-               {
-                 warning (OPT_Wformat, "too few arguments for format");
-                 return;
-               }
-
-             cur_param = TREE_VALUE (params);
-             params = TREE_CHAIN (params);
+                cur_param = NULL;
+              else
+                {
+                  cur_param = TREE_VALUE (params);
+                  params = TREE_CHAIN (params);
+                }
 
              wanted_type_ptr->wanted_type = wanted_type;
              wanted_type_ptr->wanted_type_name = wanted_type_name;
@@ -2257,9 +2259,11 @@ check_format_info_main (format_check_results *res,
                  if (strchr (fci->flags2, 'R') != 0)
                    wanted_type_ptr->reading_from_flag = 1;
                }
-             wanted_type_ptr->name = NULL;
+              wanted_type_ptr->kind = CF_KIND_FORMAT;
              wanted_type_ptr->param = cur_param;
              wanted_type_ptr->arg_num = arg_num;
+             wanted_type_ptr->format_start = format_start;
+             wanted_type_ptr->format_length = format_chars - format_start;
              wanted_type_ptr->next = NULL;
              if (last_wanted_type != 0)
                last_wanted_type->next = wanted_type_ptr;
@@ -2280,17 +2284,26 @@ check_format_info_main (format_check_results *res,
        }
 
       if (first_wanted_type != 0)
-       check_format_types (first_wanted_type, format_start,
-                           format_chars - format_start);
+        check_format_types (first_wanted_type);
+    }
+
+  if (format_chars - orig_format_chars != format_length)
+    warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format");
+  if (info->first_arg_num != 0 && params != 0
+      && has_operand_number <= 0)
+    {
+      res->number_other--;
+      res->number_extra_args++;
     }
+  if (has_operand_number > 0)
+    finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
 }
 
 
 /* Check the argument types from a single format conversion (possibly
    including width and precision arguments).  */
 static void
-check_format_types (format_wanted_type *types, const char *format_start,
-                   int format_length)
+check_format_types (format_wanted_type *types)
 {
   for (; types != 0; types = types->next)
     {
@@ -2301,12 +2314,7 @@ check_format_types (format_wanted_type *types, const char *format_start,
       int arg_num;
       int i;
       int char_type_flag;
-      cur_param = types->param;
-      cur_type = TREE_TYPE (cur_param);
-      if (cur_type == error_mark_node)
-       continue;
-      orig_cur_type = cur_type;
-      char_type_flag = 0;
+
       wanted_type = types->wanted_type;
       arg_num = types->arg_num;
 
@@ -2319,6 +2327,19 @@ check_format_types (format_wanted_type *types, const char *format_start,
 
       wanted_type = TYPE_MAIN_VARIANT (wanted_type);
 
+      cur_param = types->param;
+      if (!cur_param)
+        {
+          format_type_warning (types, wanted_type, NULL);
+          continue;
+        }
+
+      cur_type = TREE_TYPE (cur_param);
+      if (cur_type == error_mark_node)
+       continue;
+      orig_cur_type = cur_type;
+      char_type_flag = 0;
+
       STRIP_NOPS (cur_param);
 
       /* Check the types of any additional pointer arguments
@@ -2382,10 +2403,7 @@ check_format_types (format_wanted_type *types, const char *format_start,
            }
          else
            {
-             format_type_warning (types->name, format_start, format_length,
-                                  wanted_type, types->pointer_count,
-                                  types->wanted_type_name, orig_cur_type,
-                                  arg_num);
+              format_type_warning (types, wanted_type, orig_cur_type);
              break;
            }
        }
@@ -2437,33 +2455,34 @@ check_format_types (format_wanted_type *types, const char *format_start,
          && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
        continue;
       /* Now we have a type mismatch.  */
-      format_type_warning (types->name, format_start, format_length,
-                          wanted_type, types->pointer_count,
-                          types->wanted_type_name, orig_cur_type, arg_num);
+      format_type_warning (types, wanted_type, orig_cur_type);
     }
 }
 
 
 /* Give a warning about a format argument of different type from that
-   expected.  DESCR is a description such as "field precision", or
-   NULL for an ordinary format.  For an ordinary format, FORMAT_START
-   points to where the format starts in the format string and
-   FORMAT_LENGTH is its length.  WANTED_TYPE is the type the argument
-   should have after POINTER_COUNT pointer dereferences.
-   WANTED_NAME_NAME is a possibly more friendly name of WANTED_TYPE,
-   or NULL if the ordinary name of the type should be used.  ARG_TYPE
-   is the type of the actual argument.  ARG_NUM is the number of that
-   argument.  */
+   expected.  WANTED_TYPE is the type the argument should have, possibly
+   stripped of pointer dereferences.  The description (such as "field
+   precision"), the placement in the format string, a possibly more
+   friendly name of WANTED_TYPE, and the number of pointer dereferences
+   are taken from TYPE.  ARG_TYPE is the type of the actual argument,
+   or NULL if it is missing.  */
 static void
-format_type_warning (const char *descr, const char *format_start,
-                    int format_length, tree wanted_type, int pointer_count,
-                    const char *wanted_type_name, tree arg_type, int arg_num)
+format_type_warning (format_wanted_type *type, tree wanted_type, tree arg_type)
 {
+  int kind = type->kind;
+  const char *wanted_type_name = type->wanted_type_name;
+  const char *format_start = type->format_start;
+  int format_length = type->format_length;
+  int pointer_count = type->pointer_count;
+  int arg_num = type->arg_num;
+
   char *p;
   /* If ARG_TYPE is a typedef with a misleading name (for example,
      size_t but not the standard size_t expected by printf %zu), avoid
      printing the typedef name.  */
   if (wanted_type_name
+      && arg_type
       && TYPE_NAME (arg_type)
       && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
       && DECL_NAME (TYPE_NAME (arg_type))
@@ -2489,28 +2508,36 @@ format_type_warning (const char *descr, const char *format_start,
       memset (p + 1, '*', pointer_count);
       p[pointer_count + 1] = 0;
     }
+
   if (wanted_type_name)
     {
-      if (descr)
-       warning (OPT_Wformat, "%s should have type %<%s%s%>, "
-                "but argument %d has type %qT",
-                descr, wanted_type_name, p, arg_num, arg_type);
+      if (arg_type)
+        warning (OPT_Wformat, "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
+                 "but argument %d has type %qT",
+                 gettext (kind_descriptions[kind]),
+                 (kind == CF_KIND_FORMAT ? "%" : ""),
+                 format_length, format_start, 
+                 wanted_type_name, p, arg_num, arg_type);
       else
-       warning (OPT_Wformat, "format %q.*s expects type %<%s%s%>, "
-                "but argument %d has type %qT",
-                format_length, format_start, wanted_type_name, p,
-                arg_num, arg_type);
+        warning (OPT_Wformat, "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
+                 gettext (kind_descriptions[kind]),
+                 (kind == CF_KIND_FORMAT ? "%" : ""),
+                 format_length, format_start, wanted_type_name, p);
     }
   else
     {
-      if (descr)
-       warning (OPT_Wformat, "%s should have type %<%T%s%>, "
-                "but argument %d has type %qT",
-                descr, wanted_type, p, arg_num, arg_type);
+      if (arg_type)
+        warning (OPT_Wformat, "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
+                 "but argument %d has type %qT",
+                 gettext (kind_descriptions[kind]),
+                 (kind == CF_KIND_FORMAT ? "%" : ""),
+                 format_length, format_start, 
+                 wanted_type, p, arg_num, arg_type);
       else
-       warning (OPT_Wformat, "format %q.*s expects type %<%T%s%>, "
-                "but argument %d has type %qT",
-                format_length, format_start, wanted_type, p, arg_num, arg_type);
+        warning (OPT_Wformat, "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
+                 gettext (kind_descriptions[kind]),
+                 (kind == CF_KIND_FORMAT ? "%" : ""),
+                 format_length, format_start, wanted_type, p);
     }
 }
 
index 8eeb72c..ee05b7b 100644 (file)
@@ -1,3 +1,19 @@
+2010-11-13  Paolo Bonzini  <bonzini@gnu.org>
+
+       * gcc.dg/format/few-1.c: New test.
+       * gcc.dg/format/asm_fprintf-1.c: Adjust.
+       * gcc.dg/format/c90-scanf-1.c: Adjust.
+       * gcc.dg/format/cmn-err-1.c: Adjust.
+       * gcc.dg/format/dfp-printf-1.c: Adjust.
+       * gcc.dg/format/dfp-scanf-1.c: Adjust.
+       * gcc.dg/format/gcc_diag-1.c: Adjust.
+       * gcc.dg/format/ms_unnamed-1.c: Adjust.
+       * gcc.dg/format/strfmon-1.c: Adjust.
+       * gcc.dg/format/unnamed-1.c: Adjust.
+       * gcc.dg/format/xopen-2.c: Adjust.
+       * g++.dg/ext/builtin4.C: Adjust.
+       * g++.dg/ext/builtin5.C: Adjust.
+
 2010-11-12  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/pragma-diag-2.c: New test.
index 7d6c473..8804b53 100644 (file)
@@ -6,5 +6,5 @@
 extern "C" int printf(const char*,...);
 
 void foo() {
-  printf("%d");                // { dg-warning "too few arguments" }
+  printf("%d");                // { dg-warning "expects a matching" }
 }
index 2601a12..051224f 100644 (file)
@@ -8,5 +8,5 @@ namespace std {
 }
 
 void foo() {
-  std::printf("%d");           // { dg-warning "too few arguments" }
+  std::printf("%d");           // { dg-warning "expects a matching" }
 }
index 22173df..d71834a 100644 (file)
@@ -62,7 +62,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
   asm_fprintf ("%s", n); /* { dg-warning "format" "bad argument types" } */
 
   /* Wrong number of arguments.  */
-  asm_fprintf ("%d%d", i); /* { dg-warning "arguments" "wrong number of args" } */
+  asm_fprintf ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */
   asm_fprintf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
   /* Miscellaneous bogus constructions.  */
   asm_fprintf (""); /* { dg-warning "zero-length" "warning for empty format" } */
index e4c18f7..586e4af 100644 (file)
@@ -220,7 +220,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
   */
   printf ("%*.*d", u1, u2, i);
   /* Wrong number of arguments.  */
-  printf ("%d%d", i); /* { dg-warning "arguments" "wrong number of args" } */
+  printf ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */
   printf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
   /* Miscellaneous bogus constructions.  */
   printf (""); /* { dg-warning "zero-length" "warning for empty format" } */
index ea42f1e..e4803f1 100644 (file)
@@ -106,7 +106,7 @@ foo (int *ip, unsigned int *uip, short int *hp, unsigned short int *uhp,
   scanf ("%s", cs); /* { dg-warning "constant" "%s writing into const" } */
   scanf ("%p", pcp); /* { dg-warning "constant" "%p writing into const" } */
   /* Wrong number of arguments.  */
-  scanf ("%d%d", ip); /* { dg-warning "arguments" "wrong number of args" } */
+  scanf ("%d%d", ip); /* { dg-warning "matching" "wrong number of args" } */
   scanf ("%d", ip, ip); /* { dg-warning "arguments" "wrong number of args" } */
   /* Miscellaneous bogus constructions.  */
   scanf (""); /* { dg-warning "zero-length" "warning for empty format" } */
index 7e291d3..fd5ca59 100644 (file)
@@ -28,11 +28,12 @@ int main()
   cmn_err_func (0, "%16b", i, "\01Foo");
 
   cmn_err_func (0, "%i", i);           /* { dg-warning "unknown|too many" } */
-  cmn_err_func (0, "%d", l);           /* { dg-warning "expects type" } */
-  cmn_err_func (0, "%b");              /* { dg-warning "too few" } */
-  cmn_err_func (0, "%b", i);           /* { dg-warning "too few" } */
-  cmn_err_func (0, "%b", i, i);                /* { dg-warning "expects type" } */
-  cmn_err_func (0, "%b", string, i);   /* { dg-warning "expects type" } */
-  cmn_err_func (0, "%p", 3);           /* { dg-warning "expects type" } */
+  cmn_err_func (0, "%d", l);           /* { dg-warning "expects argument" } */
+  cmn_err_func (0, "%b");              /* { dg-warning "'int'" } */
+/* { dg-warning "'char \\*'" "" { target *-*-solaris2.* } 32 } */
+  cmn_err_func (0, "%b", i);           /* { dg-warning "matching" } */
+  cmn_err_func (0, "%b", i, i);                /* { dg-warning "expects argument" } */
+  cmn_err_func (0, "%b", string, i);   /* { dg-warning "expects argument" } */
+  cmn_err_func (0, "%p", 3);           /* { dg-warning "expects argument" } */
   return 0;
 }
index 7000b98..e92f161 100644 (file)
@@ -43,44 +43,44 @@ foo (_Decimal32 x, _Decimal64 y, _Decimal128 z, int i, unsigned int j,
 
   /* Check warnings for type mismatches.  */
 
-  printf ("%Hf\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HF\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%He\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HE\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%Hg\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HG\n", y); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%Hf\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HF\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%He\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HE\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%Hg\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-  printf ("%HG\n", z); /* { dg-warning "expects type" "bad use of %H" } */
-
-  printf ("%Df\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DF\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%De\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DE\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%Dg\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DG\n", x); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%Df\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DF\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%De\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DE\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%Dg\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-  printf ("%DG\n", z); /* { dg-warning "expects type" "bad use of %D" } */
-
-  printf ("%DDf\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDF\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDe\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDE\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDg\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDG\n", x);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDf\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDF\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDe\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDE\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDg\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
-  printf ("%DDG\n", y);        /* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%Hf\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HF\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%He\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HE\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%Hg\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HG\n", y); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%Hf\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HF\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%He\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HE\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%Hg\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+  printf ("%HG\n", z); /* { dg-warning "expects argument" "bad use of %H" } */
+
+  printf ("%Df\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DF\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%De\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DE\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%Dg\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DG\n", x); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%Df\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DF\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%De\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DE\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%Dg\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+  printf ("%DG\n", z); /* { dg-warning "expects argument" "bad use of %D" } */
+
+  printf ("%DDf\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDF\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDe\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDE\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDg\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDG\n", x);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDf\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDF\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDe\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDE\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDg\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
+  printf ("%DDG\n", y);        /* { dg-warning "expects argument" "bad use of %DD" } */
 
   /* Check for warnings for bad use of H, D, and DD length specifiers.  */
 
index b72da5b..ffa12a8 100644 (file)
@@ -43,44 +43,44 @@ voo (_Decimal32 *x, _Decimal64 *y, _Decimal128 *z, int *i, unsigned int *j,
 
   /* Check warnings for type mismatches.  */
 
-  scanf ("%Hf", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HF", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%He", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HE", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%Hg", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HG", y);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%Hf", z);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HF", z);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%He", z);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HE", z);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%Hg", z);    /* { dg-warning "expects type" "bad use of %H" } */
-  scanf ("%HG", z);    /* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%Hf", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HF", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%He", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HE", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%Hg", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HG", y);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%Hf", z);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HF", z);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%He", z);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HE", z);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%Hg", z);    /* { dg-warning "expects argument" "bad use of %H" } */
+  scanf ("%HG", z);    /* { dg-warning "expects argument" "bad use of %H" } */
 
-  scanf ("%Df", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DF", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%De", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DE", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%Dg", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DG", x);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%Df", z);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DF", z);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%De", z);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DE", z);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%Dg", z);    /* { dg-warning "expects type" "bad use of %D" } */
-  scanf ("%DG", z);    /* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%Df", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DF", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%De", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DE", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%Dg", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DG", x);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%Df", z);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DF", z);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%De", z);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DE", z);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%Dg", z);    /* { dg-warning "expects argument" "bad use of %D" } */
+  scanf ("%DG", z);    /* { dg-warning "expects argument" "bad use of %D" } */
 
-  scanf ("%DDf", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDF", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDe", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDE", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDg", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDG", x);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDf", y);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDF", y);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDe", y);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDE", y);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDg", y);   /* { dg-warning "expects type" "bad use of %DD" } */
-  scanf ("%DDG", y);   /* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDf", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDF", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDe", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDE", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDg", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDG", x);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDf", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDF", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDe", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDE", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDg", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
+  scanf ("%DDG", y);   /* { dg-warning "expects argument" "bad use of %DD" } */
 
   /* Check for warnings for bad use of H, D, and DD length specifiers.  */
 
diff --git a/gcc/testsuite/gcc.dg/format/few-1.c b/gcc/testsuite/gcc.dg/format/few-1.c
new file mode 100644 (file)
index 0000000..6e0d35b
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89 -Wformat" } */
+
+int f(int *ip, char *cp)
+{
+       __builtin_printf ("%*.*s");
+/* { dg-warning "field width specifier '\\*' expects a matching 'int' argument" "" { target *-*-* } 6 } */
+/* { dg-warning "field precision specifier '\\.\\*' expects a matching 'int' argument" "" { target *-*-* } 6 } */
+/* { dg-warning "format '%s' expects a matching 'char \\*' argument" "" { target *-*-* } 6 } */
+       __builtin_printf ("%*.*s", ip, *cp);
+/* { dg-warning "field width specifier '\\*' expects argument of type 'int'" "" { target *-*-* } 10 } */
+/* { dg-warning "format '%s' expects a matching 'char \\*' argument" "" { target *-*-* } 10 } */
+       __builtin_printf ("%s %i", ip, ip);
+/* { dg-warning "format '%s' expects argument of type 'char \\*'" "" { target *-*-* } 13 } */
+/* { dg-warning "format '%i' expects argument of type 'int'" "" { target *-*-* } 13 } */
+       __builtin_printf ("%s %i", cp);
+/* { dg-warning "format '%i' expects a matching 'int' argument" "" { target *-*-* } 16 } */
+       __builtin_printf ("%lc");
+/* { dg-warning "format '%lc' expects a matching 'wint_t' argument" "" { target *-*-* } 18 } */
+       __builtin_printf ("%lc", cp);
+/* { dg-warning "format '%lc' expects argument of type 'wint_t'" "" { target *-*-* } 20 } */
+       __builtin_scanf ("%s");
+/* { dg-warning "format '%s' expects a matching 'char \\*' argument" "" { target *-*-* } 22 } */
+       __builtin_scanf ("%i", cp);
+/* { dg-warning "format '%i' expects argument of type 'int \\*'" "" { target *-*-* } 24 } */
+       __builtin_scanf ("%lc");
+/* { dg-warning "format '%lc' expects a matching 'wchar_t \\*' argument" "" { target *-*-* } 26 } */
+       __builtin_scanf ("%lc", cp);
+/* { dg-warning "format '%lc' expects argument of type 'wchar_t \\*'" "" { target *-*-* } 28 } */
+}
index f88965f..953c944 100644 (file)
@@ -201,7 +201,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
   diag ("%s", n); /* { dg-warning "format" "bad argument types" } */
 
   /* Wrong number of arguments.  */
-  diag ("%d%d", i); /* { dg-warning "arguments" "wrong number of args" } */
+  diag ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */
   diag ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
   /* Miscellaneous bogus constructions.  */
   diag (""); /* { dg-warning "zero-length" "warning for empty format" } */
index 8c8ff03..fddd347 100644 (file)
@@ -19,7 +19,7 @@
 void
 f (TItype x)
 {
-  printf("%d", x); /* { dg-warning "expects type" } */
-  printf("%d", 141592653589793238462643383279502884197169399375105820974944); /* { dg-warning "expects type" } */
+  printf("%d", x); /* { dg-warning "expects argument" } */
+  printf("%d", 141592653589793238462643383279502884197169399375105820974944); /* { dg-warning "expects argument" } */
   /* { dg-warning "unsigned only|too large" "constant" { target *-*-* } 23 } */
 }
index d163751..934242a 100644 (file)
@@ -54,7 +54,7 @@ foo (char *s, size_t m, double d, long double ld)
   strfmon (s, m, "%.5%\n"); /* { dg-warning "format" "bogus %%" } */
   strfmon (s, m, "%#5%\n"); /* { dg-warning "format" "bogus %%" } */
   /* Miscellaneous bogus formats.  */
-  strfmon (s, m, "%n%n", d); /* { dg-warning "arguments" "too few args" } */
+  strfmon (s, m, "%n%n", d); /* { dg-warning "matching" "too few args" } */
   strfmon (s, m, ""); /* { dg-warning "zero-length" "empty" } */
   strfmon (s, m, NULL); /* { dg-warning "null" "null format string" } */
   strfmon (s, m, "%"); /* { dg-warning "trailing" "tailing %" } */
index b3efdcb..6d8cd39 100644 (file)
@@ -19,7 +19,7 @@
 void
 f (TItype x)
 {
-  printf("%d", x); /* { dg-warning "expects type" } */
-  printf("%d", 141592653589793238462643383279502884197169399375105820974944); /* { dg-warning "expects type" } */
+  printf("%d", x); /* { dg-warning "expects argument" } */
+  printf("%d", 141592653589793238462643383279502884197169399375105820974944); /* { dg-warning "expects argument" } */
   /* { dg-warning "unsigned only|too large" "constant" { target *-*-* } 23 } */
 }
index 5b83731..4aee191 100644 (file)
@@ -16,6 +16,6 @@ void
 foo (int i, int j, va_list va)
 {
   printf("%2$*1$c", i, j);
-  printf("%2$*1$c %2$*1$c", i, j); /* { dg-bogus "too few" "bogus too few dollar" } */
-  vbar(va, "%*s"); /* { dg-bogus "too few" "bogus too few vprintf" } */
+  printf("%2$*1$c %2$*1$c", i, j); /* { dg-bogus "matching" "bogus too few dollar" } */
+  vbar(va, "%*s"); /* { dg-bogus "matching" "bogus too few vprintf" } */
 }