Message ID | 5160963D.6090308@net-b.de |
---|---|
State | New |
Headers | show |
Tobias Burnus <burnus@net-b.de> writes: > gcc.dg/Wunprototyped-calls.c:13:3: warning: call to function ‘g’ without a > real prototype [-Wunprototyped-calls] What is a real prototype? Andreas.
On Sat, Apr 6, 2013 at 11:50 PM, Andreas Schwab <schwab@linux-m68k.org> wrote: > Tobias Burnus <burnus@net-b.de> writes: > >> gcc.dg/Wunprototyped-calls.c:13:3: warning: call to function ‘g’ without a >> real prototype [-Wunprototyped-calls] > > What is a real prototype? One reason I didn't bother to upstream that patch is language lawyer legalise ... We want to catch int foo (); int bar (T x) { return foo (x); } int foo (U) { ... } that is, calling foo () from a context where the definition or declaration with argument specification is not visible. This causes the C frontend to apply var-args promotion rules to all arguments which may differ from promotion rules that would be applied when a "real prototype" was visible at the point of the function call. I'd just say "without a prototype". int foo(); or just foo(); is specified as part of 6.7.5.3/14 as "The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied." (this appears mostly in K&R style programs where the T D ( identifier-list(opt) ) form is valid). I am not sure that GCC doing varargs style promotions to calls with only this kind of declarator is valid or if the program would be rejected by K&R (and only the GCC extension of varargs functions without a first named arguments makes us do what we do ...). The patch was implemented while hunting down "miscompiles" in either X or ghostscript (I don't remember...). Richard. > Andreas. > > -- > Andreas Schwab, schwab@linux-m68k.org > GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 > "And now for something completely different."
Richard Biener <richard.guenther@gmail.com> writes:
> when a "real prototype" was visible
How is that different from a prototype?
Andreas.
On Mon, Apr 8, 2013 at 3:05 PM, Andreas Schwab <schwab@linux-m68k.org> wrote: > Richard Biener <richard.guenther@gmail.com> writes: > >> when a "real prototype" was visible > > How is that different from a prototype? It's different from the case where a K&R definition was seen and thus type information is present via that mechanism. We don't want to warn in that case. As I suggested, the warning should just print "without a prototype" but "prototype" here means that a definition before the call is enough to make us happy (as opposed to -Wstrict-prototypes which warns about function definitions without a previous prototype we want to warn about calls to functions without a definition or a prototype). Any better suggestion? Richard. > Andreas. > > -- > Andreas Schwab, schwab@linux-m68k.org > GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 > "And now for something completely different."
Richard Biener <richard.guenther@gmail.com> writes: > On Mon, Apr 8, 2013 at 3:05 PM, Andreas Schwab <schwab@linux-m68k.org> wrote: >> Richard Biener <richard.guenther@gmail.com> writes: >> >>> when a "real prototype" was visible >> >> How is that different from a prototype? > > It's different from the case where a K&R definition was seen and thus > type information is present via that mechanism. We don't want to > warn in that case. But that isn't a prototype. > As I suggested, the warning should just print "without a prototype" > but "prototype" here means that a definition before the call is > enough to make us happy (as opposed to -Wstrict-prototypes which > warns about function definitions without a previous prototype we > want to warn about calls to functions without a definition or a prototype). How does a definition help here if it isn't a prototype? Andreas.
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);