From patchwork Sat Apr 6 21:40:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 234452 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 8AB7B2C0090 for ; Sun, 7 Apr 2013 07:40:30 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=iRdnjkFDdHV222dLAGEfnRKhV2lxX7/3xIbKLggRGwB 9DXeDXsOpq/zEkseErQYBnBeuNeWFnIehk/lmdMLu0nf6+kbFdCYMByD3TIq4pz/ ezZIQR/+oIQZuFCk0uZH2U5Vi4M7MD/dqk2S+0QW1KC3ZvDUe/Zlu8UkFa+AXBWE = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=RzVrONlloiriO1xOgiBnBYXJLpY=; b=pM5mQsgMMfM3BQ41Q zPta/Z5h+o+kPrrD9f34/asgNojOSHi+ALUkLhrL5W7jRRK3eGDVy2R9ewN2qHc+ 1SbJyKKrh9Tz91e1r/QrEEmnmDvFhc885HT+pcdo+tJosiRPoWDH8Ewp9UkVdaXs ZSxSAZKKmyL+IYxd2OEFbKu+xQ= Received: (qmail 19117 invoked by alias); 6 Apr 2013 21:40:23 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19106 invoked by uid 89); 6 Apr 2013 21:40:23 -0000 X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, TW_CX autolearn=ham version=3.3.1 Received: from mx02.qsc.de (HELO mx02.qsc.de) (213.148.130.14) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sat, 06 Apr 2013 21:40:18 +0000 Received: from archimedes.net-b.de (port-92-195-88-1.dynamic.qsc.de [92.195.88.1]) by mx02.qsc.de (Postfix) with ESMTP id AE4C4278C2; Sat, 6 Apr 2013 23:40:14 +0200 (CEST) Message-ID: <5160963D.6090308@net-b.de> Date: Sat, 06 Apr 2013 23:40:13 +0200 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130307 Thunderbird/17.0.4 MIME-Version: 1.0 To: gcc patches CC: "Joseph S. Myers" Subject: C: Add new warning -Wunprototyped-calls X-Virus-Found: No 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 Tobias Burnus * c.opt (Wunprototyped-calls): New C/ObjC warning. * c-opts.c (c_common_handle_option): Handle it. gcc/c/ 2013-04-07 Richard Biener * c-typeck.c (build_function_call_vec): Handle warning warn_unprototyped_calls. gcc/ 2013-04-07 Tobias Burnus * doc/invoke.texi (-Wunprototyped-calls): Document it. (-Wall): Add -Wunprototyped-calls to the list. gcc/testsuite/ 2013-04-07 Richard Biener Tobias Burnus * 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);