This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C: Add new warning -Wunprototyped-calls
- From: Tobias Burnus <burnus at net-b dot de>
- To: gcc patches <gcc-patches at gcc dot gnu dot org>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Sat, 06 Apr 2013 23:40:13 +0200
- Subject: 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);