OSDN Git Service

* c-common.c (warn_format, warn_format_y2k,
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Dec 2000 22:43:33 +0000 (22:43 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Dec 2000 22:43:33 +0000 (22:43 +0000)
warn_format_extra_args, warn_format_nonliteral): Define.
(check_format_info): Check warn_format_nonliteral and
warn_format_extra_args.
(check_format_info_main): Check warn_format_y2k.
(set_Wformat): New function.
* c-common.h (warn_format_y2k, warn_format_extra_args,
warn_format_nonliteral, set_Wformat): Declare.
* c-decl.c (warn_format): Remove definition.
(c_decode_option): Handle -Wformat-nonliteral,
-Wno-format-extra-args and -Wno-format-y2k, and negated versions.
Use set_Wformat.
* invoke.texi: Document these new options and -Wformat=2.
* toplev.c (documented_lang_options): Add these new options.

cp:
* decl2.c (warn_format): Remove definition.
(lang_decode_option): Handle -Wformat-nonliteral,
-Wno-format-extra-args and -Wno-format-y2k.  Use set_Wformat.

testsuite:
* gcc.dg/format-no-exargs-1.c, gcc.dg/format-no-y2k-1.c,
gcc.dg/format-nonlit-1.c, gcc.dg/format-nonlit-2.c: New tests.

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

13 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format-no-exargs-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/format-no-y2k-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/format-nonlit-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/format-nonlit-2.c [new file with mode: 0644]
gcc/toplev.c

index 509dfc9..cea2915 100644 (file)
@@ -1,5 +1,22 @@
 2000-12-01  Joseph S. Myers  <jsm28@cam.ac.uk>
 
+       * c-common.c (warn_format, warn_format_y2k,
+       warn_format_extra_args, warn_format_nonliteral): Define.
+       (check_format_info): Check warn_format_nonliteral and
+       warn_format_extra_args.
+       (check_format_info_main): Check warn_format_y2k.
+       (set_Wformat): New function.
+       * c-common.h (warn_format_y2k, warn_format_extra_args,
+       warn_format_nonliteral, set_Wformat): Declare.
+       * c-decl.c (warn_format): Remove definition.
+       (c_decode_option): Handle -Wformat-nonliteral,
+       -Wno-format-extra-args and -Wno-format-y2k, and negated versions.
+       Use set_Wformat.
+       * invoke.texi: Document these new options and -Wformat=2.
+       * toplev.c (documented_lang_options): Add these new options.
+
+2000-12-01  Joseph S. Myers  <jsm28@cam.ac.uk>
+
        * builtins.def (BUILT_IN_IMAXABS): Add.
        * builtins.c (expand_builtin): Also abort on BUILT_IN_IMAXABS.
        * c-common.c (c_common_nodes_and_builtins): Create builtin
index c4fd463..e07a7d3 100644 (file)
@@ -173,6 +173,22 @@ int flag_no_nonansi_builtin;
 
 const char *flag_dump_translation_unit;
 
+/* Warn about *printf or *scanf format/argument anomalies. */
+
+int warn_format;
+
+/* Warn about Y2K problems with strftime formats.  */
+
+int warn_format_y2k;
+
+/* Warn about excess arguments to formats.  */
+
+int warn_format_extra_args;
+
+/* Warn about non-literal format arguments.  */
+
+int warn_format_nonliteral;
+
 /* Nonzero means warn about possible violations of sequence point rules.  */
 
 int warn_sequence_point;
@@ -2321,7 +2337,7 @@ 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 > 1)
+      if (info->first_arg_num != 0 && warn_format_nonliteral)
        status_warning (status, "format not a string literal, argument types not checked");
     }
 
@@ -2333,10 +2349,10 @@ check_format_info (status, info, params)
      If the format is an empty string, this should be counted similarly to the
      case of extra format arguments.  */
   if (res.number_extra_args > 0 && res.number_non_literal == 0
-      && res.number_other == 0)
+      && res.number_other == 0 && warn_format_extra_args)
     status_warning (status, "too many arguments for format");
   if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
-      && res.number_other == 0)
+      && res.number_other == 0 && warn_format_extra_args)
     status_warning (status, "unused arguments in $-style format");
   if (res.number_empty > 0 && res.number_non_literal == 0
       && res.number_other == 0)
@@ -2991,23 +3007,24 @@ check_format_info_main (status, res, info, format_chars, format_length,
        }
 
       /* Give Y2K warnings.  */
-      {
-       int y2k_level = 0;
-       if (strchr (fci->flags2, '4') != 0)
-         if (strchr (flag_chars, 'E') != 0)
+      if (warn_format_y2k)
+       {
+         int y2k_level = 0;
+         if (strchr (fci->flags2, '4') != 0)
+           if (strchr (flag_chars, 'E') != 0)
+             y2k_level = 3;
+           else
+             y2k_level = 2;
+         else if (strchr (fci->flags2, '3') != 0)
            y2k_level = 3;
-         else
+         else if (strchr (fci->flags2, '2') != 0)
            y2k_level = 2;
-       else if (strchr (fci->flags2, '3') != 0)
-         y2k_level = 3;
-       else if (strchr (fci->flags2, '2') != 0)
-         y2k_level = 2;
-       if (y2k_level == 3)
-         status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
-                         format_char);
-       else if (y2k_level == 2)
-         status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
-      }
+         if (y2k_level == 3)
+           status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
+                           format_char);
+         else if (y2k_level == 2)
+           status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
+       }
 
       if (strchr (fci->flags2, '[') != 0)
        {
@@ -3325,6 +3342,19 @@ check_format_types (status, types)
       }
     }
 }
+
+/* Set format warning options according to a -Wformat=n option.  */
+
+void
+set_Wformat (setting)
+     int setting;
+{
+  warn_format = setting;
+  warn_format_y2k = setting;
+  warn_format_extra_args = setting;
+  if (setting != 1)
+    warn_format_nonliteral = setting;
+}
 \f
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
index b7253c6..7ada212 100644 (file)
@@ -349,6 +349,18 @@ extern int flag_const_strings;
 
 extern int warn_format;
 
+/* Warn about Y2K problems with strftime formats.  */
+
+extern int warn_format_y2k;
+
+/* Warn about excess arguments to formats.  */
+
+extern int warn_format_extra_args;
+
+/* Warn about non-literal format arguments.  */
+
+extern int warn_format_nonliteral;
+
 /* Warn about possible violations of sequence point rules.  */
 
 extern int warn_sequence_point;
@@ -441,6 +453,7 @@ extern void declare_function_name           PARAMS ((void));
 extern void decl_attributes                    PARAMS ((tree, tree, tree));
 extern void init_function_format_info          PARAMS ((void));
 extern void check_function_format              PARAMS ((int *, tree, tree, tree));
+extern void set_Wformat                                PARAMS ((int));
 extern void c_apply_type_quals_to_decl         PARAMS ((int, tree));
 /* Print an error message for invalid operands to arith operation CODE.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
index e7c5988..1c1f138 100644 (file)
@@ -421,10 +421,6 @@ int warn_redundant_decls = 0;
 
 int warn_nested_externs = 0;
 
-/* Warn about *printf or *scanf format/argument anomalies.  */
-
-int warn_format;
-
 /* Warn about a subscript that has type char.  */
 
 int warn_char_subscripts = 0;
@@ -710,11 +706,23 @@ c_decode_option (argc, argv)
   else if (!strcmp (p, "-Wno-traditional"))
     warn_traditional = 0;
   else if (!strncmp (p, "-Wformat=", 9))
-    warn_format = atol (p + 9);
+    set_Wformat (atoi (p + 9));
   else if (!strcmp (p, "-Wformat"))
-    warn_format = 1;
+    set_Wformat (1);
   else if (!strcmp (p, "-Wno-format"))
-    warn_format = 0;
+    set_Wformat (0);
+  else if (!strcmp (p, "-Wformat-y2k"))
+    warn_format_y2k = 1;
+  else if (!strcmp (p, "-Wno-format-y2k"))
+    warn_format_y2k = 0;
+  else if (!strcmp (p, "-Wformat-extra-args"))
+    warn_format_extra_args = 1;
+  else if (!strcmp (p, "-Wno-format-extra-args"))
+    warn_format_extra_args = 0;
+  else if (!strcmp (p, "-Wformat-nonliteral"))
+    warn_format_nonliteral = 1;
+  else if (!strcmp (p, "-Wno-format-nonliteral"))
+    warn_format_nonliteral = 0;
   else if (!strcmp (p, "-Wchar-subscripts"))
     warn_char_subscripts = 1;
   else if (!strcmp (p, "-Wno-char-subscripts"))
@@ -793,7 +801,7 @@ c_decode_option (argc, argv)
       warn_return_type = 1;
       set_Wunused (1);
       warn_switch = 1;
-      warn_format = 1;
+      set_Wformat (1);
       warn_char_subscripts = 1;
       warn_parentheses = 1;
       warn_sequence_point = 1;
index 6c51126..de75ee9 100644 (file)
@@ -1,5 +1,11 @@
 2000-12-01  Joseph S. Myers  <jsm28@cam.ac.uk>
 
+       * decl2.c (warn_format): Remove definition.
+       (lang_decode_option): Handle -Wformat-nonliteral,
+       -Wno-format-extra-args and -Wno-format-y2k.  Use set_Wformat.
+
+2000-12-01  Joseph S. Myers  <jsm28@cam.ac.uk>
+
        * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
        (init_decl_processing): Don't create string_type_node,
        const_string_type_node, wint_type_node, intmax_type_node,
index 00017aa..497db61 100644 (file)
@@ -269,10 +269,6 @@ int warn_sign_compare;
 
 int warn_float_equal = 0;
 
-/* Warn about *printf or *scanf format/argument anomalies.  */
-
-int warn_format;
-
 /* Warn about functions which might be candidates for format attributes.  */
 
 int warn_missing_format_attribute;
@@ -723,7 +719,13 @@ lang_decode_option (argc, argv)
       else if (!strcmp (p, "float-equal"))
        warn_float_equal = setting;
       else if (!strcmp (p, "format"))
-       warn_format = setting;
+       set_Wformat (setting);
+      else if (!strcmp (p, "format-y2k"))
+       warn_format_y2k = setting;
+      else if (!strcmp (p, "format-extra-args"))
+       warn_format_extra_args = setting;
+      else if (!strcmp (p, "format-nonliteral"))
+       warn_format_nonliteral = setting;
       else if (!strcmp (p, "missing-format-attribute"))
        warn_missing_format_attribute = setting;
       else if (!strcmp (p, "conversion"))
@@ -772,7 +774,7 @@ lang_decode_option (argc, argv)
          set_Wunused (setting);
          warn_implicit = setting;
          warn_switch = setting;
-         warn_format = setting;
+         set_Wformat (setting);
          warn_parentheses = setting;
          warn_missing_braces = setting;
          warn_sign_compare = setting;
index b71580c..4118ab5 100644 (file)
@@ -143,7 +143,8 @@ in the following sections.
 -w  -W  -Wall  -Waggregate-return
 -Wcast-align  -Wcast-qual  -Wchar-subscripts  -Wcomment
 -Wconversion  -Wdisabled-optimization -Werror
--Wfloat-equal  -Wformat
+-Wfloat-equal  -Wformat  -Wformat=2
+-Wformat-nonliteral
 -Wid-clash-@var{len}  -Wimplicit -Wimplicit-int 
 -Wimplicit-function-declaration
 -Werror-implicit-function-declaration
@@ -151,7 +152,8 @@ in the following sections.
 -Wlarger-than-@var{len}  -Wlong-long
 -Wmain  -Wmissing-declarations
 -Wmissing-format-attribute  -Wmissing-noreturn
--Wmultichar  -Wno-import  -Wpacked  -Wpadded
+-Wmultichar  -Wno-format-extra-args -Wno-format-y2k
+-Wno-import  -Wpacked  -Wpadded
 -Wparentheses -Wpointer-arith  -Wredundant-decls
 -Wreturn-type  -Wsequence-point  -Wshadow
 -Wsign-compare  -Wswitch  -Wsystem-headers
@@ -1548,6 +1550,30 @@ Check calls to @code{printf} and @code{scanf}, etc., to make sure that
 the arguments supplied have types appropriate to the format string
 specified.
 
+@samp{-Wformat} is included in @samp{-Wall}.  For more control over some
+aspects of format checking, the options @samp{-Wno-format-y2k},
+@samp{-Wno-format-extra-args}, @samp{-Wformat-nonliteral} and
+@samp{-Wformat=2} are available, but are not included in @samp{-Wall}.
+
+@item -Wno-format-y2k
+If @samp{-Wformat} is specified, do not warn about @code{strftime}
+formats which may yield only a two-digit year.
+
+@item -Wno-format-extra-args
+If @samp{-Wformat} is specified, do not warn about excess arguments to a
+@code{printf} or @code{scanf} format function.  The C standard specifies
+that such arguments are ignored.
+
+@item -Wformat-nonliteral
+If @samp{-Wformat} is specified, also warn if the format string is not a
+string literal and so cannot be checked, unless the format function
+takes its format arguments as a @code{va_list}.
+
+@item -Wformat=2
+Enable @samp{-Wformat} plus format checks not included in
+@samp{-Wformat}.  Currently equivalent to @samp{-Wformat
+-Wformat-nonliteral}.
+
 @item -Wimplicit-int
 Warn when a declaration does not specify a type.
 
index 53cbfc0..3b353e7 100644 (file)
@@ -1,3 +1,8 @@
+2000-12-01  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * gcc.dg/format-no-exargs-1.c, gcc.dg/format-no-y2k-1.c,
+       gcc.dg/format-nonlit-1.c, gcc.dg/format-nonlit-2.c: New tests.
+
 2000-12-01  Neil Booth  <neilb@earthling.net>
 
         * gcc.dg/cpp/20000720-1.S: Remove duplicate testcase.
diff --git a/gcc/testsuite/gcc.dg/format-no-exargs-1.c b/gcc/testsuite/gcc.dg/format-no-exargs-1.c
new file mode 100644 (file)
index 0000000..bbf5a8a
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test for warnings for extra format arguments being disabled by
+   -Wno-format-extra-args.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat -Wno-format-extra-args" } */
+
+extern int printf (const char *, ...);
+
+void
+foo (int i)
+{
+  printf ("foo", i);
+  printf ("%1$d", i, i);
+}
diff --git a/gcc/testsuite/gcc.dg/format-no-y2k-1.c b/gcc/testsuite/gcc.dg/format-no-y2k-1.c
new file mode 100644 (file)
index 0000000..e41d26d
--- /dev/null
@@ -0,0 +1,16 @@
+/* Test for warnings for Y2K problems being disabled by -Wno-format-y2k.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat -Wno-format-y2k" } */
+
+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)
+{
+  strftime (s, m, "%y%c%x", tp);
+}
diff --git a/gcc/testsuite/gcc.dg/format-nonlit-1.c b/gcc/testsuite/gcc.dg/format-nonlit-1.c
new file mode 100644 (file)
index 0000000..dfcd84b
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test for warnings for non-string-literal formats.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat -Wformat-nonliteral" } */
+
+extern int printf (const char *, ...);
+
+void
+foo (char *s, int i)
+{
+  printf ((const char *)i, i); /* { dg-warning "argument types" "non-literal" } */
+  printf (s, i); /* { dg-warning "argument types" "non-literal" } */
+}
diff --git a/gcc/testsuite/gcc.dg/format-nonlit-2.c b/gcc/testsuite/gcc.dg/format-nonlit-2.c
new file mode 100644 (file)
index 0000000..c20ed08
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test for warnings for non-string-literal formats.  Test with -Wformat=2.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -Wformat=2" } */
+
+extern int printf (const char *, ...);
+
+void
+foo (char *s, int i)
+{
+  printf ((const char *)i, i); /* { dg-warning "argument types" "non-literal" } */
+  printf (s, i); /* { dg-warning "argument types" "non-literal" } */
+}
index b2d8ea0..db9e6f8 100644 (file)
@@ -1226,8 +1226,16 @@ documented_lang_options[] =
   { "-Wno-comments", "" },
   { "-Wconversion", "Warn about possibly confusing type conversions" },
   { "-Wno-conversion", "" },
-  { "-Wformat", "Warn about printf format anomalies" },
+  { "-Wformat", "Warn about printf/scanf/strftime format anomalies" },
   { "-Wno-format", "" },
+  { "-Wformat-y2k", "" },
+  { "-Wno-format-y2k",
+    "Don't warn about strftime formats yielding 2 digit years" },
+  { "-Wformat-extra-args", "" },
+  { "-Wno-format-extra-args",
+    "Don't warn about too many arguments to format functions" },
+  { "-Wformat-nonliteral", "Warn about non-string-literal format strings" },
+  { "-Wno-format-nonliteral", "" },
   { "-Wimplicit-function-declaration",
     "Warn about implicit function declarations" },
   { "-Wno-implicit-function-declaration", "" },