CHERI C aims to support everything in the standard and most things programmers do. A function pointer in CHERI C does not embed type info and is a single pointer-sized value, so can even be stored in a void* (which works almost everywhere, but not on weird Harvard architecture and so a lot of C code assumes it works everywhere). But you must cast it to the correct type before calling because the various CHERI C ABIs pass all on-stack arguments via a (bounded) pointer and so mismatches can result in run-time traps.
Some CHERI C ABIs have used a descriptor model (Morello has hardware support for this) where a function pointer is actually a pointer to a pair of a code and data pointer, which lets you invoke a library function and atomically gain access to its code and data.