Currently even when I prototype double exp10 (double);
this function is not available to optimizers for code generation if they just check for builtin_decl_implicit (BUILT_IN_EXP10). Curiously though the function is identified as BUILT_IN_EXP10 when used though, thus the middle-end assumes it has expected exp10 semantics. I see we already cheat with stpcpy and make it available to optimizers by marking it implicit when we've seen a prototype. The following patch proposed to do that for all builtins. At least I can't see how interpreting exp10 as exp10 but then not being allowed to use it as exp10 is sensible. Now one could argue that declaring exp10 doesn't mean there is an implementation available at link time (after all declaring exp10 doesn't mean I use exp10 anywhere). But that's true for implicit decls as well - I might declare 'pow', not use it and not link against libm. So if the compiler now emits a call to pow my link will break: extern double pow (double, double); double x; int main () { return x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x; } links fine with -O0 but fails to link with -Os -ffast-math where I have to supply -lm. So the following patch extends the stpcpy assumption to all builtins. Ok after bootstrap / regtest? Thanks, Richard. 2014-12-04 Richard Biener <rguent...@suse.de> c/ * c-decl.c (merge_decls): For explicit builtin functions mark them as implicit when we have seen a compatible prototype. cp/ * decl.c (duplicate_decls): For explicit builtin functions mark them as implicit when we have seen a compatible prototype. Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c (revision 218343) +++ gcc/c/c-decl.c (working copy) @@ -2563,18 +2563,11 @@ merge_decls (tree newdecl, tree olddecl, if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL) { enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl); - switch (fncode) - { - /* If a compatible prototype of these builtin functions - is seen, assume the runtime implements it with the - expected semantics. */ - case BUILT_IN_STPCPY: - if (builtin_decl_explicit_p (fncode)) - set_builtin_decl_implicit_p (fncode, true); - break; - default: - break; - } + /* If a compatible prototype of a builtin function + is seen, assume the runtime implements it with the + expected semantics. */ + if (builtin_decl_explicit_p (fncode)) + set_builtin_decl_implicit_p (fncode, true); } } else Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 218343) +++ gcc/cp/decl.c (working copy) @@ -2288,18 +2288,11 @@ duplicate_decls (tree newdecl, tree oldd if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL) { enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl); - switch (fncode) - { - /* If a compatible prototype of these builtin functions - is seen, assume the runtime implements it with the - expected semantics. */ - case BUILT_IN_STPCPY: - if (builtin_decl_explicit_p (fncode)) - set_builtin_decl_implicit_p (fncode, true); - break; - default: - break; - } + /* If a compatible prototype of a builtin function + is seen, assume the runtime implements it with the + expected semantics. */ + if (builtin_decl_explicit_p (fncode)) + set_builtin_decl_implicit_p (fncode, true); } } if (new_defines_function)