A function-pointer parameter's signature is not compared, so a callback arity change reads NO_CHANGE on the header path (2026-10-15)¶
Status (2026-10-24): FIXED for the header (castxml) path; OPEN on DWARF. castxml function types now spell their full declarator (EXTRACTOR_GENERATION 16); see the index entry. Originally (2026-10-15): reproduced in plain C, so this is not Rust-specific.
Repro:
/* old.c, new.c: typedef int (*cb_t)(int); -> typedef int (*cb_t)(int, int);
int set_cb(cb_t cb); (same declaration in both headers) */
abicheck compare libold.so libnew.so -H old=old.h -H new=new.h reports NO_CHANGE, and the DWARF-only comparison of the same two .so files also reports NO_CHANGE. The inline spelling int set_cb(int (*cb)(int)) vs (int, int) is also NO_CHANGE.
The parameter record stores type: "cb_t" (or nothing, inline) with kind: pointer. The signature of the function the pointer points at is not part of the record, so no comparator sees it.
Rust exposes the same gap unevenly:
Option<extern "C" fn(i32) -> i32>is caught on the DWARF path, but only because its generic type name carries the signature. That is a side effect of naming, not a comparison of signatures.- A raw
extern "C" fn(c_int) -> c_intparameter isNO_CHANGEon the DWARF path too.
Fix direction: capture the return type and parameter list of the pointee for function-pointer parameters and typedefs, in both the castxml and DWARF extractors, and compare them as a signature. This changes the type representation in model/, so it is not patched here.
Index: Known gaps