https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86125
--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
It looks like this is on purpose. match_builtin_function_types, the function
that determines whether a declaration of a built-in matches its expected type,
has the following comment:
/* Subroutine of compare_decls. Allow harmless mismatches in return
and argument types provided that the type modes match. This function
returns a unified type given a suitable match, and 0 otherwise. */
and it uses TYPE_MODE (type) to decide whether return and argument types are
compatible. That makes size_t and char* match on targets where they are the
same size, and ditto for int and char*.
C++, on the other hand, handles this more sanely and diagnoses the mismatch in
both cases:
c.c:2:7: warning: declaration of ‘char* strdup(int)’ conflicts with built-in
declaration ‘char* strdup(const char*)’ [-Wbuiltin-declaration-mismatch]
char* strdup (int); // warning
^~~~~~
c.c:3:7: warning: declaration of ‘char* strlen(const char*)’ conflicts with
built-in declaration ‘long unsigned int strlen(const char*)’
[-Wbuiltin-declaration-mismatch]
char* strlen (const char*); // warning
^~~~~~