https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89586
Bug ID: 89586 Summary: warning: cast between incompatible function types when building libobjc Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libobjc Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- This warning is emitted during gcc bootstrap from the time warning for invalid function casts was introduced: /space/homedirs/uros/gcc-svn/trunk/libobjc/sendmsg.c: In function ‘__objc_get_forward_imp’: /space/homedirs/uros/gcc-svn/trunk/libobjc/sendmsg.c:129:16: warning: cast between incompatible function types from ‘__big (*)(struct objc_object *, const struct objc_selector *, ...)’ {aka ‘struct <anonymous> (*)(struct objc_object *, const struct objc_selector *, ...)’} to ‘struct objc_object * (*)(struct objc_object *, const struct objc_selector *, ...)’ [-Wcast-function-type] 129 | return (IMP)__objc_block_forward; | ^ /space/homedirs/uros/gcc-svn/trunk/libobjc/sendmsg.c:131:16: warning: cast between incompatible function types from ‘double (*)(struct objc_object *, const struct objc_selector *, ...)’ to ‘struct objc_object * (*)(struct objc_object *, const struct objc_selector *, ...)’ [-Wcast-function-type] 131 | return (IMP)__objc_double_forward; | ^ We have following snippets in libobjc/sendmsg.c: --cut here-- /* Various forwarding functions that are used based upon the return type for the selector. __objc_block_forward for structures. __objc_double_forward for floats/doubles. __objc_word_forward for pointers or types that fit in registers. */ static double __objc_double_forward (id, SEL, ...); static id __objc_word_forward (id, SEL, ...); typedef struct { id many[8]; } __big; #if INVISIBLE_STRUCT_RETURN static __big #else static id #endif __objc_block_forward (id, SEL, ...); ... /* Given a selector, return the proper forwarding implementation. */ inline IMP __objc_get_forward_imp (id rcv, SEL sel) { ... return (IMP)__objc_block_forward; else if (t && (*t == 'f' || *t == 'd')) return (IMP)__objc_double_forward; else return (IMP)__objc_word_forward; } } --cut here-- with IMP defined in libobjc/objc/objc.h: --cut here-- /* An 'id' is an object of an unknown class. The way the object data is stored inside the object is private and what you see here is only the beginning of the actual struct. The first field is always a pointer to the Class that the object belongs to. */ typedef struct objc_object { /* 'class_pointer' is the Class that the object belongs to. In case of a Class object, this pointer points to the meta class. Compatibility Note: The Apple/NeXT runtime calls this field 'isa'. To access this field, use object_getClass() from runtime.h, which is an inline function so does not add any overhead and is also portable to other runtimes. */ Class class_pointer; } *id; /* 'IMP' is a C function that implements a method. When retrieving the implementation of a method from the runtime, this is the type of the pointer returned. The idea of the definition of IMP is to represent a 'pointer to a general function taking an id, a SEL, followed by other unspecified arguments'. You must always cast an IMP to a pointer to a function taking the appropriate, specific types for that function, before calling it - to make sure the appropriate arguments are passed to it. The code generated by the compiler to perform method calls automatically does this cast inside method calls. */ typedef id (*IMP)(id, SEL, ...); --cut here--