GCC silently accepts calls to built-in functions declared without a prototype as long as the arguments match the expected types (based on the prototype hardcoded into GCC), but issues warnings for calls where the arguments don't match. But GCC makes no attempt to make sure that in calls to other (i.e., non-built-in) functions declared without prototype provided arguments have the same type across all the calls. Diagnosing mismatches as suggested in the comments below would help detect bugs caused by their incompatibily. This enhancement is different from pr92212 which is about calls to K&R functions defined in the same translation unit. $ cat x.c && gcc -O2 -S -Wall x.c char* strchr (); char* f0 (const char *s) { return strchr (s, 'x'); // no warning (okay) } char* f1 (const char *s) { return strchr (s, "y"); // warning (good) } void g (); void h (void) { g (1); // (presumably) okay, f's type is 'void (int)' g ("foo"); // should be diagnosed g (1, "bar"); // ditto } x.c: In function ‘f1’: x.c:10:21: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [-Wint-conversion] 10 | return strchr (s, "y"); // warning (good) | ^~~ | | | char * x.c:1:7: note: expected ‘int’ but argument is of type ‘char *’ 1 | char* strchr (); | ^~~~~~
Is this like clang's -Wknr-promoted-parameter? https://clang.llvm.org/docs/DiagnosticsReference.html#wknr-promoted-parameter
Current Clang warns like this: t.c:17:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype] g (1); // (presumably) okay, f's type is 'void (int)' ^ t.c:18:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype] g ("foo"); // should be diagnosed ^ t.c:19:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype] g (1, "bar"); // ditto ^ Maybe that's sufficient? Trying to infer the type of g from its uses seems to be rather questionable. For K&R projects, GCC already has -flto -Wlto-type-mismatch, which can diagnose violations across translation units.
I don't think we need to go beyond that (I don't really care about the uses). That'll make this a dupe of/depends on PR108694?
Patch posted: [PATCH] c: Implement -Wdeprecated-non-prototype <https://inbox.sourceware.org/gcc-patches/87plmwyue3.fsf@oldenburg.str.redhat.com/> This is what the new warning produces for the input from the description: t.c: In function ‘f0’: t.c:5:10: warning: ISO C23 does not allow arguments for function ‘strchr’ declared without parameters [-Wdeprecated-non-prototype] 5 | return strchr (s, 'x'); // no warning (okay) | ^~~~~~ t.c:1:7: note: declared here 1 | char* strchr (); | ^~~~~~ t.c: In function ‘f1’: t.c:10:10: warning: ISO C23 does not allow arguments for function ‘strchr’ declared without parameters [-Wdeprecated-non-prototype] 10 | return strchr (s, "y"); // warning (good) | ^~~~~~ t.c:1:7: note: declared here 1 | char* strchr (); | ^~~~~~ t.c:10:21: error: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [-Wint-conversion] 10 | return strchr (s, "y"); // warning (good) | ^~~ | | | char * t.c:1:7: note: expected ‘int’ but argument is of type ‘char *’ 1 | char* strchr (); | ^~~~~~ t.c: In function ‘h’: t.c:17:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype] 17 | g (1); // (presumably) okay, f's type is 'void (int)' | ^ t.c:13:6: note: declared here 13 | void g (); | ^ t.c:18:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype] 18 | g ("foo"); // should be diagnosed | ^ t.c:13:6: note: declared here 13 | void g (); | ^ t.c:19:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype] 19 | g (1, "bar"); // ditto | ^ t.c:13:6: note: declared here 13 | void g (); | ^
The trunk branch has been updated by Florian Weimer <fw@gcc.gnu.org>: https://gcc.gnu.org/g:701d8e7e60b85809cae348c1e9edb3b0f4924325 commit r15-5369-g701d8e7e60b85809cae348c1e9edb3b0f4924325 Author: Florian Weimer <fweimer@redhat.com> Date: Sun Nov 17 19:42:33 2024 +0100 c: Implement -Wdeprecated-non-prototype This warning covers the C23 incompibilities resulting from using () as parameter lists in function declarations. The warning name comes from Clang. The implementation is not perfect because GCC treats these two declarations as equivalent: void f (); void f (not_a_type); This is a bit confusing because they are clearly visually distinct. However, as of GCC 14, the second form is an error by default, so treating both the same as far as -Wdeprecated-non-prototype does not seem so bad from a user experience view. gcc/c-family/ PR c/95445 * c-opts.cc (c_common_post_options): Initialize warn_deprecated_non_prototype. * c.opt (Wdeprecated-non-prototype): New option. * c.opt.urls: Regenerate. gcc/c/ PR c/95445 * c-decl.cc (start_function): Warn about parameters after parameter-less declaration. * c-typeck.cc (build_function_call_vec): Pass fntype to convert_arguments. (convert_arguments): Change argument to fntype and compute typelist. Warn about parameter list mismatches on first parameter. gcc/ PR c/95445 * doc/invoke.texi: Document -Wdeprecated-non-prototype. gcc/testsuite/ PR c/95445 * gcc.dg/Wdeprecated-non-prototype-1.c: New test. * gcc.dg/Wdeprecated-non-prototype-2.c: New test. * gcc.dg/Wdeprecated-non-prototype-3.c: New test. * gcc.dg/Wdeprecated-non-prototype-4.c: New test.
Fixed for GCC 15.