Hello Gabriel,

Following your request[1], please find below the implementation for the
-Wvarargs option, as well as its introductory text.  It applies on top
the changes to enable -ftrack-macro-expansion by default[2].

[1]: http://gcc.gnu.org/ml/gcc-patches/2012-04/msg01604.html
[2]: http://gcc.gnu.org/ml/gcc-patches/2012-04/msg00532.html

---
Several warnings related to questionable usage cases of variadic
function related macros (like va_start) could not be controlled by any
warning-related macro.  Fixed thus, by introducing the -Wvarargs option.

Tested on x86_64-unknown-linux-gnu against trunk.  Bootstrap for all
languages is still underway.

gcc/c-family/

        * c.opt (Wvarargs):  Define new option.

gcc/
        builtins.c (fold_builtin_next_arg):  Use OPT_Wvarargs as an
        argument for the various warning_at calls.

gcc/doc/

        * invoke.texi: Update the documentation.

gcc/testsuite/

        * c-c++-common/Wvarargs.c: New test case.
        * c-c++-common/Wvarargs-2.c: Likewise.
---
 gcc/builtins.c                          |    8 ++--
 gcc/c-family/c.opt                      |    4 ++
 gcc/doc/invoke.texi                     |    7 ++++
 gcc/testsuite/c-c++-common/Wvarargs-2.c |   33 +++++++++++++++++++
 gcc/testsuite/c-c++-common/Wvarargs.c   |   54 +++++++++++++++++++++++++++++++
 5 files changed, 102 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wvarargs-2.c
 create mode 100644 gcc/testsuite/c-c++-common/Wvarargs.c

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5ddc47b..41a052b 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -12127,8 +12127,8 @@ fold_builtin_next_arg (tree exp, bool va_start_p)
          /* Evidently an out of date version of <stdarg.h>; can't validate
             va_start's second argument, but can still work as intended.  */
          warning_at (current_location,
-                     0,
-                     "%<__builtin_next_arg%> called without an argument");
+                     OPT_Wvarargs,
+                  "%<__builtin_next_arg%> called without an argument");
          return true;
        }
       else if (nargs > 1)
@@ -12164,7 +12164,7 @@ fold_builtin_next_arg (tree exp, bool va_start_p)
             argument so that we will get wrong-code because of
             it.  */
          warning_at (current_location,
-                     0,
+                     OPT_Wvarargs,
                      "second parameter of %<va_start%> not last named 
argument");
        }
 
@@ -12177,7 +12177,7 @@ fold_builtin_next_arg (tree exp, bool va_start_p)
       else if (DECL_REGISTER (arg))
        {
          warning_at (current_location,
-                     0,
+                     OPT_Wvarargs,
                      "undefined behaviour when second parameter of "
                      "%<va_start%> is declared with %<register%> storage");
        }
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index db8ca81..a038e57 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -685,6 +685,10 @@ Wvariadic-macros
 C ObjC C++ ObjC++ Warning
 Do not warn about using variadic macros when -pedantic
 
+Wvarargs
+C ObjC C++ ObjC++ Warning Var(warn_varargs) Init(1)
+Warn about questionable usage of the macros used to retrieve variable arguments
+
 Wvla
 C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
 Warn if a variable length array is used
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 280fac3..47100b0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -4657,6 +4657,13 @@ Warn if variadic macros are used in pedantic ISO C90 
mode, or the GNU
 alternate syntax when in pedantic ISO C99 mode.  This is default.
 To inhibit the warning messages, use @option{-Wno-variadic-macros}.
 
+@item -Wvarargs
+@opindex Wvarargs
+@opindex Wno-varargs
+Warn upon questionable usage of the macros used to handle variable
+arguments like @samp{va_start}.  This is default.  To inhibit the
+warning messages, use @option{-Wno-varargs}.
+
 @item -Wvector-operation-performance
 @opindex Wvector-operation-performance
 @opindex Wno-vector-operation-performance
diff --git a/gcc/testsuite/c-c++-common/Wvarargs-2.c 
b/gcc/testsuite/c-c++-common/Wvarargs-2.c
new file mode 100644
index 0000000..a2e031f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wvarargs-2.c
@@ -0,0 +1,33 @@
+/*
+   { dg-options "-Wno-varargs" }
+   { dg-do compile }
+ */
+
+#include <stdarg.h>
+
+void
+err (int a)
+{
+  va_list vp;
+  va_start (vp, a); // { dg-error "used in function with fixed args" }
+}
+
+void
+foo0 (int a, int b, ...)
+{
+    va_list vp;
+    /* 'a' is not the last argument of the enclosing function, but
+       don't warn because we are ignoring -Wvarargs.  */
+    va_start (vp, a);
+    va_end (vp);
+}
+
+void
+foo1 (int a, register int b, ...)
+{
+    va_list vp;
+    /* 'b' is declared with register storage, but don't warn
+       because we are ignoring -Wvarargs.  */
+    va_start (vp, b);
+    va_end (vp);
+}
diff --git a/gcc/testsuite/c-c++-common/Wvarargs.c 
b/gcc/testsuite/c-c++-common/Wvarargs.c
new file mode 100644
index 0000000..408f427
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wvarargs.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+
+#include <stdarg.h>
+
+void
+err (int a)
+{
+  va_list vp;
+  va_start (vp, a); // { dg-error "used in function with fixed args" }
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wvarargs"
+
+void
+foo0 (int a, int b, ...)
+{
+    va_list vp;
+    /* 'a' is not the last argument of the enclosing function, but
+       don't warn because we are ignoring -Wvarargs.  */
+    va_start (vp, a);
+    va_end (vp);
+}
+
+void
+foo1 (int a, register int b, ...)
+{
+    va_list vp;
+    /* 'b' is declared with register storage, but don't warn
+       because we are ignoring -Wvarargs.  */
+    va_start (vp, b);
+    va_end (vp);
+}
+
+#pragma GCC diagnostic pop
+
+void
+foo2 (int a, int b, ...)
+{
+    va_list vp;
+    /* 'a' is not the last argument of the enclosing function, so
+       warn.  */
+    va_start (vp, a); /* { dg-warning "second parameter" } */
+    va_end (vp);
+}
+
+void
+foo3 (int a, register int b, ...)
+{
+    va_list vp;
+    /* 'b' is declared with register storage, so warn.  */
+    va_start (vp, b); /* { dg-warning "undefined behaviour" } */
+    va_end (vp);
+}
-- 
                Dodji

Reply via email to