With the exception of built-ins with the ellipsis (like sprintf),
GCC silently accepts declarations of built-in functions without
prototypes as well as calls to such functions with any numbers
or types of arguments, compatible or otherwise. Calls with
arguments whose number and types match exactly those of
the built-in are considered by the middle-end for optimization.
Other calls (compatible or not, irrespective of whether their
number matches the number expected by the function) are then
made to the library functions.
Attached is a small fix to -Wbuiltin-declaration-mismatch to
have it diagnose built-in declarations without a prototype.
The warning is enabled by default so it causes a fair number
of tests to fail because of declarations like 'void abort();'
The breakdown of the built-ins behind the test failures is
below.
Before I take the time to clean up the test suite let me post
what I have in case going this route is not acceptable. As
an alternative, I could try to avoid some of these warnings,
e.g., by diagnosing incompatible calls instead but I think
it's even less worthwhile for built-ins than trying to do
it for ordinary functions with -Wstrict-prototypes. There
is, in my view, no justification today for standard functions
to be declared without a prototype. (I could also make
the warning depend on language mode and -Wpedantic if that
were more preferable.)
Martin
About 115 tests fail due to incompatible declarations of
the built-in functions below (the number shows the number
of warnings for each functions):
428 abort
58 exit
36 memcpy
17 memmove
15 realloc
14 cabs
5 strncpy
4 strcmp
3 alloca
2 rindex
1 aligned_alloc
PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration without prototype
gcc/c/ChangeLog:
PR c/83656
* c-decl.c (diagnose_mismatched_decls): Diagnose declarations of
built-in functions without a prototype.
gcc/testsuite/ChangeLog:
PR c/83656
* gcc.dg/Wbuiltin-declaration-mismatch-5.c: New test.
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 6c9e667..7008176 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -2088,15 +2088,29 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
can't validate the argument list) the built-in definition is
overridden, but optionally warn this was a bad choice of name. */
if (DECL_BUILT_IN (olddecl)
- && !C_DECL_DECLARED_BUILTIN (olddecl)
- && (!TREE_PUBLIC (newdecl)
- || (DECL_INITIAL (newdecl)
- && !prototype_p (TREE_TYPE (newdecl)))))
+ && !C_DECL_DECLARED_BUILTIN (olddecl))
{
- warning (OPT_Wshadow, "declaration of %q+D shadows "
- "a built-in function", newdecl);
- /* Discard the old built-in function. */
- return false;
+ if (!TREE_PUBLIC (newdecl)
+ || (DECL_INITIAL (newdecl)
+ && !prototype_p (TREE_TYPE (newdecl))))
+ {
+ warning_at (DECL_SOURCE_LOCATION (newdecl),
+ OPT_Wshadow, "declaration of %qD shadows "
+ "a built-in function", newdecl);
+ /* Discard the old built-in function. */
+ return false;
+ }
+
+ if (!prototype_p (TREE_TYPE (newdecl)))
+ {
+ warning_at (DECL_SOURCE_LOCATION (newdecl),
+ OPT_Wbuiltin_declaration_mismatch,
+ "declaration of built-in function %qD without "
+ "a prototype; expected %qT",
+ newdecl, TREE_TYPE (olddecl));
+ /* Discard the old built-in function. */
+ return false;
+ }
}
if (DECL_INITIAL (newdecl))
diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c
new file mode 100644
index 0000000..51a634d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c
@@ -0,0 +1,10 @@
+/* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
+ without prototype
+ { dg-do compile }
+ { dg-options "-Wbuiltin-declaration-mismatch" } */
+
+void* memcpy (); /* { dg-warning "declaration of built-in function .memcpy. without a prototype; expected .void \\\*\\\(void \\\*, const void \\\*, \(long \)?unsigned int\\\)." } */
+
+int strcmp (); /* { dg-warning "declaration of built-in function .strcmp. without a prototype; expected .int\\\(const char* \\\*, const char \\\*\\\)." } */
+
+int strcpy (); /* { dg-warning "conflicting types for built-in function .strcpy.; expected .char \\\*\\\(char \\\*, const char \\\*\\\)." } */