This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C: Add new warning -Wunprototyped-calls


This patch comes from Richard's SUSE GCC patch. There, -Wunprototyped-calls is enabled for all RPM builds.

-Wunprototyped-calls prints a warning if one calls a function with an argument with is declared without prototype. For instance:

gcc.dg/Wunprototyped-calls.c: In function âmainâ:
gcc.dg/Wunprototyped-calls.c:13:3: warning: call to function âgâ without a real prototype [-Wunprototyped-calls]
g(1); /* { dg-warning "call to function 'g' without a real prototype" } */
^
gcc.dg/Wunprototyped-calls.c:7:6: note: âgâ was declared here
void g() { } /* { dg-message "note: 'g' was declared here" } */


To avoid too many warning, no warning is shows for K&R procedures or if no argument is passed to the function. (i.e. for those where the programmer just forgot the "(void)".)

The warning can help finding argument-passing bugs and it is less intrusive than -Wstrict-prototypes.


The patch activates the warning with -Wall, but one could also argue that it should only be activated with -Wextra or only with -Wunprototyped-calls.


Bootstrapped (C,ObjC,C++,ObjC++ only) and regtested on x86-64-gnu-linux.
OK for the trunk?

Tobias
gcc/c-family/
2013-04-07  Richard Biener  <rguenther@suse.de>
	    Tobias Burnus  <burnus@net-b.de>

	* c.opt (Wunprototyped-calls): New C/ObjC warning.
	* c-opts.c (c_common_handle_option): Handle it.

gcc/c/
2013-04-07  Richard Biener  <rguenther@suse.de>

	* c-typeck.c (build_function_call_vec): Handle warning
	warn_unprototyped_calls.

gcc/
2013-04-07  Tobias Burnus  <burnus@net-b.de>

	* doc/invoke.texi (-Wunprototyped-calls): Document it.
	(-Wall): Add -Wunprototyped-calls to the list.

gcc/testsuite/
2013-04-07  Richard Biener  <rguenther@suse.de>
	    Tobias Burnus  <burnus@net-b.de>

	* gcc.dg/cleanup-1.c: Update dg-warning.
	* gcc.dg/Wunprototyped-calls.c: New.

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 4b6990a..a66e2a6 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -444,6 +444,10 @@ c_common_handle_option (size_t scode, const char *arg, int value,
       warn_unknown_pragmas = value * 2;
       break;
 
+    case OPT_Wunprototyped_calls:
+      warn_unprototyped_calls = value;
+      break;
+
     case OPT_ansi:
       if (!c_dialect_cxx ())
 	set_std_c89 (false, true);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 10ae84d..9c2de33 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -757,6 +757,10 @@ Wunused-local-typedefs
 C ObjC C++ ObjC++ Var(warn_unused_local_typedefs) Warning EnabledBy(Wunused)
 Warn when typedefs locally defined in a function are not used
 
+Wunprototyped-calls
+C ObjC Var(warn_unprototyped_calls) Warning LangEnabledBy(C ObjC,Wall)
+Warn about calls to unprototyped functions with at least one argument
+
 Wunused-macros
 C ObjC C++ ObjC++ Var(cpp_warn_unused_macros) Warning
 Warn about macros defined in the main file that are not used
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index ddb6d39..26336b3 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2833,6 +2833,19 @@ build_function_call_vec (location_t loc, tree function,
       && !check_builtin_function_arguments (fundecl, nargs, argarray))
     return error_mark_node;
 
+  /* If we cannot check function arguments because a prototype is
+     missing for the callee, warn here.  */
+  if (warn_unprototyped_calls
+      && nargs > 0 && !TYPE_ARG_TYPES (fntype)
+      && fundecl && !DECL_BUILT_IN (fundecl) && !C_DECL_IMPLICIT (fundecl)
+      && !DECL_ARGUMENTS (fundecl))
+    {
+      if (warning (OPT_Wunprototyped_calls,
+		   "call to function %qD without a real prototype", fundecl))
+	inform (DECL_SOURCE_LOCATION (fundecl), "%qD was declared here",
+		fundecl);
+    }
+
   /* Check that the arguments to the function are valid.  */
   check_function_arguments (fntype, nargs, argarray);
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1652ebc..ee1a351 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -279,8 +279,8 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-Wbad-function-cast  -Wmissing-declarations @gol
 -Wmissing-parameter-type  -Wmissing-prototypes  -Wnested-externs @gol
 -Wold-style-declaration  -Wold-style-definition @gol
--Wstrict-prototypes  -Wtraditional  -Wtraditional-conversion @gol
--Wdeclaration-after-statement -Wpointer-sign}
+-Wstrict-prototypes -Wunprototyped-calls -Wtraditional @gol
+-Wtraditional-conversion -Wdeclaration-after-statement -Wpointer-sign}
 
 @item Debugging Options
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
@@ -3144,6 +3144,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 -Wtrigraphs  @gol
 -Wuninitialized  @gol
 -Wunknown-pragmas  @gol
+-Wunprototyped-calls @r{(only for C/ObjC)} @gol
 -Wunused-function  @gol
 -Wunused-label     @gol
 -Wunused-value     @gol
@@ -4455,6 +4456,15 @@ argument types.  (An old-style function definition is permitted without
 a warning if preceded by a declaration that specifies the argument
 types.)
 
+@item -Wunprototyped-calls @r{(C and Objective-C only)}
+@opindex Wunprototyped-calls
+@opindex Wno-unprototyped-calls
+Warn if a function is called using at least one argument when that
+function is declared or defined without specifying the argument types.
+Note that no warning is issued for functions without prototype
+which are declared in K&R style.  This warning is also enabled
+by @option{-Wall}.
+
 @item -Wold-style-declaration @r{(C and Objective-C only)}
 @opindex Wold-style-declaration
 @opindex Wno-old-style-declaration
diff --git a/gcc/testsuite/gcc.dg/Wunprototyped-calls.c b/gcc/testsuite/gcc.dg/Wunprototyped-calls.c
new file mode 100644
index 0000000..e87c844
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunprototyped-calls.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunprototyped-calls" } */
+/* Validate expected warnings and errors.  */
+
+/* All the following functions do not have a prototype. */
+void f() {  }
+void g() {  } /* { dg-message "note: 'g' was declared here" } */
+void h(i) int i; {  }
+
+
+int main() {
+  f();		/* OK, seemingly only "(void)" forgotten.  */
+  g(1);  /* { dg-warning "call to function 'g' without a real prototype" } */
+  h(5);		/* OK, K&R declaration; accept old code */
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cleanup-1.c b/gcc/testsuite/gcc.dg/cleanup-1.c
index 48b8264..0f395cb 100644
--- a/gcc/testsuite/gcc.dg/cleanup-1.c
+++ b/gcc/testsuite/gcc.dg/cleanup-1.c
@@ -6,7 +6,7 @@
 #define C(x)	__attribute__((cleanup(x)))
 
 static int f1(void *x U) { return 0; }
-static void f2() { }
+static void f2() { } /* { dg-message "declared here" "" } */
 static void f3(void) { } /* { dg-message "note: declared here" } */
 static void f4(void *x U) { }
 static void f5(int *x U) { }
@@ -18,7 +18,7 @@ static void f9(int x U) { } /* { dg-message "note: expected '\[^\n'\]*' but argu
 void test(void)
 {
   int o1 C(f1);
-  int o2 C(f2);
+  int o2 C(f2);		/* { dg-warning "without a real prototype" } */
   int o3 C(f3);		/* { dg-error "too many arguments" } */
   int o4 C(f4);
   int o5 C(f5);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]