ptitei created this revision.
ptitei added a reviewer: cfe-commits.
Implementation for C only warning -Wstrict-prototypes. Function declarations
which have no parameters specified are diagnosed and also K&R function
definitions with more than 0 parameters which are not preceded by previous
prototype declaration.
http://reviews.llvm.org/D16533
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaType.cpp
test/Sema/warn-strict-prototypes.c
Index: test/Sema/warn-strict-prototypes.c
===
--- test/Sema/warn-strict-prototypes.c
+++ test/Sema/warn-strict-prototypes.c
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+// function declaration with unspecified params
+void foo1(); // expected-warning{{this function declaration is not a prototype}}
+// CHECK: fix-it:"{{.*}}":{5:11-5:11}:"void"
+// function declaration with 0 params
+void foo2(void);
+
+// function definition with 0 params(for both cases), valid according to 6.7.5.3/14
+void foo1() {}
+void foo2(void) {}
+
+// function type typedef unspecified params
+typedef void foo3(); // expected-warning{{this function declaration is not a prototype}}
+// CHECK: fix-it:"{{.*}}":{15:19-15:19}:"void"
+void bar1(void) {
+ foo3 *fp = 0;
+ (*fp)();
+}
+
+// global fp unspecified params
+void (*foo4)(); // expected-warning{{this function declaration is not a prototype}}
+// CHECK: fix-it:"{{.*}}":{23:14-23:14}:"void"
+
+// struct member fp unspecified params
+struct { void (*foo5)(); } s; // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{27:23-27:23}:"void"
+
+// param fp unspecified params
+void bar2(void (*foo6)()) { // expected-warning{{this function declaration is not a prototype}}
+// CHECK: fix-it:"{{.*}}":{31:24-31:24}:"void"
+ // local fp unspecified params
+ void (*foo7)() = 0; // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{34:16-34:16}:"void"
+ // array fp unspecified params
+ void (*foo8[2])() = {0}; // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{37:19-37:19}:"void"
+ // use them
+ foo4();
+ s.foo5();
+ foo6();
+ foo7();
+ foo8[0]();
+}
+
+// function type cast using using an anonymous function declaration
+void bar3(int a) {
+ // casting function w/out prototype to unspecified params function type
+ (void)(void(*)()) foo1; // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{50:18-50:18}:"void"
+ // .. specified params
+ (void)(void(*)(void)) foo1;
+
+ // casting function w/ prototype to unspecified params function type
+ (void)(void(*)()) foo2; // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{56:18-56:18}:"void"
+ // .. specified params
+ (void)(void(*)(void)) foo2;
+}
+
+// K&R function definition not preceded by full prototype
+int foo9(a, b) // expected-warning{{old-style function definition is not preceded by a prototype}}
+ int a, b;
+{
+ return a + b;
+}
+
+// Function declaration with no types
+void foo10(); // expected-warning{{this function declaration is not a prototype}}
+ // CHECK: fix-it:"{{.*}}":{70:12-70:12}:"void"
+// K&R function definition with incomplete param list declared
+void foo10(p, p2) void *p; {} // expected-warning{{old-style function definition is not preceded by a prototype}}
+
+// Prototype declaration
+void foo11(int p, int p2);
+// K&R function definition with previous prototype declared is not diagnosed.
+void foo11(p, p2) int p; int p2; {}
Index: lib/Sema/SemaType.cpp
===
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -3919,6 +3919,20 @@
if (FTI.isAmbiguous)
warnAboutAmbiguousFunction(S, D, DeclType, T);
+ // GNU warning -Wstrict-prototypes
+ // Warn if function declaration is without prototype.
+ // This warning is issued for all kinds of unprototyped function
+ // declarations (i.e. function type typedef, function pointer etc.)
+ // C99 6.7.5.3p14:
+ // 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.
+ if (D.getFunctionDefinitionKind() == FDK_Declaration &&
+ FTI.NumParams == 0 && !LangOpts.CPlusPlus) {
+ S.Diag(DeclType.Loc, diag::warn_strict_prototypes) << 0
+ << FixItHint::CreateInsertion(FTI.getRParenLoc(), "void