@@ -2920,6 +2920,11 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
}
}
} else if (base_type && base_type->type == SYM_FN) {
+ if (base_type->ctype.base_type == &incomplete_ctype) {
+ warning(decl->pos, "'%s()' has implicit return type",
+ show_ident(decl->ident));
+ base_type->ctype.base_type = &int_ctype;
+ }
/* K&R argument declaration? */
if (lookup_type(token))
return parse_k_r_arguments(token, decl, list);
@@ -2931,6 +2936,10 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
} else if (base_type == &void_ctype && !(decl->ctype.modifiers & MOD_EXTERN)) {
sparse_error(token->pos, "void declaration");
}
+ if (base_type == &incomplete_ctype) {
+ warning(decl->pos, "'%s' has implicit type", show_ident(decl->ident));
+ decl->ctype.base_type = &int_ctype;;
+ }
for (;;) {
if (!is_typedef && match_op(token, '=')) {
@@ -15,7 +15,7 @@ static int bar(int *p)
return g == 1;
}
-static test(void)
+static void test(void)
{
foo(&g);
bar(&g);
@@ -12,6 +12,7 @@ static undef foo(char *c)
/*
* check-name: missing type
* check-error-start
+badtype2.c:2:8: warning: 'undef' has implicit type
badtype2.c:2:14: error: Expected ; at end of declaration
badtype2.c:2:14: error: got bar
badtype2.c:3:14: error: Expected ; at end of declaration
new file mode 100644
@@ -0,0 +1,15 @@
+fun(void);
+
+foo(void) { return 1; }
+static bar(void) { return 1; }
+
+/*
+ * check-name: implicit-ret-type.c
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+implicit-ret-type.c:1:1: warning: 'fun()' has implicit return type
+implicit-ret-type.c:3:1: warning: 'foo()' has implicit return type
+implicit-ret-type.c:4:8: warning: 'bar()' has implicit return type
+ * check-error-end
+ */
new file mode 100644
@@ -0,0 +1,14 @@
+extern a;
+static b;
+c;
+
+/*
+ * check-name: implicit-type.c
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+implicit-type.c:1:8: warning: 'a' has implicit type
+implicit-type.c:2:8: warning: 'b' has implicit type
+implicit-type.c:3:1: warning: 'c' has implicit type
+ * check-error-end
+ */
@@ -6,6 +6,7 @@ static void f(int T)
/*
* check-name: typedef shadowing
* check-error-start:
+typedef_shadow.c:4:16: warning: 'T' has implicit type
typedef_shadow.c:4:18: error: Expected ; at end of declaration
typedef_shadow.c:4:18: error: got a
* check-error-end:
Currently, no warning is given for symbols for which no type is explicitely given. But for functions we received a pointless warning like here under if the returned type is effectively an int: warning: incorrect type in return expression (invalid types) expected incomplete type got int Fix this by issuing the warning. Also give an implicit type of int, as required by C89, to avoid pointless warning about the expected incomplete type. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- parse.c | 9 +++++++++ validation/alias-mixed.c | 2 +- validation/badtype2.c | 1 + validation/implicit-ret-type.c | 15 +++++++++++++++ validation/implicit-type.c | 14 ++++++++++++++ validation/typedef_shadow.c | 1 + 6 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 validation/implicit-ret-type.c create mode 100644 validation/implicit-type.c