https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93812
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is that c-format.c assumes that when the "format" attribute is present, handle_format_attribute has already verified it and it was ok. Unfortunately, that is not the case, because if the attribute appears on a !prototype_p function declaration, then fewer checks are performed on it compared to when it appears on a prototype_p function, and if the !prototype_p function decl is then merged with a prototype_p function decl, nothing performs the checking. So, one way out of this is drop the validated_p stuff and always validate,, it will then behave similarly to how: __attribute__((nonnull(2))) void foo (void); warns and doesn't add the attribute, but __attribute__((nonnull(2))) void bar (); void bar (void); adds it silently (but in this case I believe it doesn't ICE when actually using the attribute). Another possibility would be to repeat the checking of the attributes which need positional_argument (nonnull, format*, alloc_size, alloc_align) when merging a !prototype_p decl with prototype_p one.