On Thu, Nov 29, 2018 at 10:42:51AM +0000, John Levon wrote: > Some environments have large amounts of legacy headers that are > pre-ANSI, and can't easily be changed. Default to complaining still, but > allow the user to turn this warning off. OK. I fully agree on the principle. I possible, we reuse for sparse the same option names than for GCC and here this new -Wnon-ansi-function-declaration option more or less covers GCC's -Wold-style-definition and -Wstrict-protoypes. For -Wold-style-definition, it matches 100%, I think. For -Wstrict-prototypes, it matches less well because currently sparse gives the warning only in the unusal double declaration: ... foo(), bar(); and not in the simpler: ... int foo(); which is explicitly accepted. I think that the warning for double cecl is actually an error because this construct is, as far as I know, as legal than the simple one and was intended to catch old style declarations like: ... foo(a) int a; So I feel like first applying a patch like: diff --git a/parse.c b/parse.c index 8232c911f..d4fa909e0 100644 --- a/parse.c +++ b/parse.c @@ -1750,7 +1750,7 @@ static enum kind which_func(struct token *token, if (next->special == ')') { /* don't complain about those */ - if (!n || match_op(next->next, ';')) + if (!n || match_op(next->next, ';') || match_op(next->next, ',')) return Empty; if (Wstrict_prototypes) warning(next->pos, and to change the current patch into something like: diff --git a/lib.c b/lib.c index 818207450..433451a58 100644 --- a/lib.c +++ b/lib.c @@ -269,6 +269,7 @@ int Wsparse_error = 0; int Wmemcpy_max_count = 1; int Wnon_pointer_null = 1; int Wold_initializer = 1; +int Wold_style_definition = 1; int Wone_bit_signed_bitfield = 1; int Woverride_init = 1; int Woverride_init_all = 0; @@ -282,6 +283,7 @@ int Wshadow = 0; int Wshift_count_negative = 1; int Wshift_count_overflow = 1; int Wsizeof_bool = 0; +int Wstrict_prototypes = 1; int Wtautological_compare = 0; int Wtransparent_union = 0; int Wtypesign = 0; @@ -705,6 +707,7 @@ static const struct flag warnings[] = { { "memcpy-max-count", &Wmemcpy_max_count }, { "non-pointer-null", &Wnon_pointer_null }, { "old-initializer", &Wold_initializer }, + { "old-style-definition", &Wold_style_definition }, { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield }, { "override-init", &Woverride_init }, { "override-init-all", &Woverride_init_all }, @@ -716,6 +719,7 @@ static const struct flag warnings[] = { { "shift-count-negative", &Wshift_count_negative }, { "shift-count-overflow", &Wshift_count_overflow }, { "sizeof-bool", &Wsizeof_bool }, + { "strict-prototypes", &Wstrict_prototypes }, { "pointer-arith", &Wpointer_arith }, { "sparse-error", &Wsparse_error }, { "tautological-compare", &Wtautological_compare }, diff --git a/lib.h b/lib.h index 14b13b676..d4e13fa12 100644 --- a/lib.h +++ b/lib.h @@ -157,6 +157,7 @@ extern int Wint_to_pointer_cast; extern int Wmemcpy_max_count; extern int Wnon_pointer_null; extern int Wold_initializer; +extern int Wold_style_definition; extern int Wone_bit_signed_bitfield; extern int Woverride_init; extern int Woverride_init_all; @@ -170,6 +171,7 @@ extern int Wshadow; extern int Wshift_count_negative; extern int Wshift_count_overflow; extern int Wsizeof_bool; +extern int Wstrict_prototypes; extern int Wtautological_compare; extern int Wtransparent_union; extern int Wtypesign; diff --git a/parse.c b/parse.c index 3e6e07425..d4fa909e0 100644 --- a/parse.c +++ b/parse.c @@ -1752,9 +1752,10 @@ static enum kind which_func(struct token *token, /* don't complain about those */ if (!n || match_op(next->next, ';') || match_op(next->next, ',')) return Empty; - warning(next->pos, - "non-ANSI function declaration of function '%s'", - show_ident(*n)); + if (Wstrict_prototypes) + warning(next->pos, + "non-ANSI function declaration of function '%s'", + show_ident(*n)); return Empty; } @@ -2792,7 +2793,9 @@ static struct token *parse_k_r_arguments(struct token *token, struct symbol *dec { struct symbol_list *args = NULL; - warning(token->pos, "non-ANSI definition of function '%s'", show_ident(decl->ident)); + if (Wold_style_definition) + warning(token->pos, "non-ANSI definition of function '%s'", show_ident(decl->ident)); + do { token = declaration_list(token, &args); if (!match_op(token, ';')) { diff --git a/validation/old-style-definition0.c b/validation/old-style-definition0.c new file mode 100644 index 000000000..eb522aa6f --- /dev/null +++ b/validation/old-style-definition0.c @@ -0,0 +1,14 @@ +extern int foo(int a, void *b); + +int foo(a, b) + int a; + void *b; +{ + if (b) + return a; +} + +/* + * check-name: old-stype-definition disabled + * check-command: sparse -Wno-old-style-definition $file + */ diff --git a/validation/old-style-definition1.c b/validation/old-style-definition1.c new file mode 100644 index 000000000..f65d7dfe3 --- /dev/null +++ b/validation/old-style-definition1.c @@ -0,0 +1,18 @@ +extern int foo(int a, void *b); + +int foo(a, b) + int a; + void *b; +{ + if (b) + return a; +} + +/* + * check-name: old-stype-definition enabled + * check-command: sparse -Wold-style-definition $file + * + * check-error-start +old-style-definition1.c:4:9: warning: non-ANSI definition of function 'foo' + * check-error-end + */ diff --git a/validation/strict-prototypes0.c b/validation/strict-prototypes0.c new file mode 100644 index 000000000..e320846b7 --- /dev/null +++ b/validation/strict-prototypes0.c @@ -0,0 +1,7 @@ +extern void func1(); +extern void myfunction(), myfunc2(); + +/* + * check-name: strict-prototypes disabled + * check-command: sparse -Wno-strict-prototypes $file + */ diff --git a/validation/strict-prototypes1.c b/validation/strict-prototypes1.c new file mode 100644 index 000000000..7e4ce6bbf --- /dev/null +++ b/validation/strict-prototypes1.c @@ -0,0 +1,14 @@ +extern void func0(); +extern void func1(), func2(); + +/* + * check-name: strict-prototypes enabled + * check-command: sparse -Wstrict-prototypes $file + * check-known-to-fail + * + * check-error-start +strict-prototypes1.c:1:18: warning: non-ANSI function declaration of function 'func0' +strict-prototypes1.c:2:18: warning: non-ANSI function declaration of function 'func1' +strict-prototypes1.c:2:27: warning: non-ANSI function declaration of function 'func2' + * check-error-end + */