On Fri, Mar 6, 2020 at 2:04 AM Martin Sebor <mse...@gmail.com> wrote: > > Treating incompatible redeclarations of built-in functions as built-ins > is a problem not just for the middle-end but even for the C front-end > itself, when different parts of it make different assumptions about > what is and isn't valid. The test case that is the subject of this > bug report (a GCC 9 and 10 regression) is one such example: it shows > that the attribute format validation assumes the function declaration > the attribute applies to has passed the prerequisite validation. But > that's not the case when the function is an incompatibly redeclared > built-in where a format attribute's positional argument refers to > parameter of an invalid/nonsensical type. > > The attached patch further adjusts the front-end to consider even more > incompatible redeclarations as built-ins: in particular, redeclarations > whose pointer arguments point to incompatible variants of unqualified > types (e.g., char* vs int*, though not char* vs const char*). > > Besides avoiding the front-end and some middle-end ICEs, the effect > of the patch is also to diagnose more incompatible redeclarations > of built-ins than before, but fewer invalid calls to such functions > (since they're no longer considered built-ins). That seems like > an unavoidable trade-off. > > Tested on x86_64-linux. Is this acceptable for GCC 10? How about 9?
The actual patch needs reviewing from a FE maintainer but I'd support putting this in for GCC 10. It would be nice if we can put in code like the following to catch "bogus" built-in declarations. I've put it in call verification because there it's where it matters most, free-lang-data would be another canonical place which would then process all "reachable" function declarations but we don't yet call free-lang-data when not doing LTO. diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f7b817d94e6..ae695891bd4 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3356,6 +3356,17 @@ verify_gimple_call (gcall *stmt) return true; } + if (fndecl + && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL) + && !types_compatible_p (TREE_TYPE (fndecl), + TREE_TYPE (builtin_decl_explicit + (DECL_FUNCTION_CODE (fndecl))))) + { + error ("function declaration declared built-in but does not " + "match expected type"); + return true; + } + tree lhs = gimple_call_lhs (stmt); if (lhs && (!is_gimple_lvalue (lhs) > Martin