https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102953
--- Comment #8 from Andrew Cooper <andrew.cooper3 at citrix dot com> --- Actually, there is a (possibly pre-existing) diagnostics issue: $ cat proto.c static void __attribute__((cf_check)) foo(void); static void __attribute__((unused)) foo(void) { } void (*ptr)(void) = foo; $ gcc -Wall -Os -fcf-protection=branch -mmanual-endbr -fcf-check-attribute=no -c proto.c -o proto.o proto.c:2:37: error: conflicting types for 'foo'; have 'void(void)' 2 | static void __attribute__((unused)) foo(void) | ^~~ proto.c:1:39: note: previous declaration of 'foo' with type 'void(void)' 1 | static void __attribute__((cf_check)) foo(void); | ^~~ The diagnostic complaining that the forward declaration doesn't match the definition gives 'void(void)' as the type in both cases, leaving out the fact that they differ by cf_check-ness.