The following reduced test exhibits the problem on MCS51. Haven't tried other targets.
#include <stdint.h>
inline int64_t test_64 (int64_t x) { return x + 20; }
inline int32_t test_32 (int32_t x) { return x + 10; }
inline int16_t test_16 (int16_t x) { return x + 5; }
#define test(x) _Generic((x), \
int16_t: test_16, \
int32_t: test_32, \
int64_t: test_64) (x)
int main (void)
{
int32_t x = 123;
test (x);
return 0;
}
It produces the following error:
?ASlink-Warning-Undefined Global '_test_32' referenced by module 'sdcc_generic_inline'
Looking at the disassembly, it really inserts an lcall _test_32 even though the function is defined as inline.
1) From the perspective of the C standard, this is not a bug: When providing a non-static inline definition of a function, programs are required to provide a non-inline one for the same function, too. Basically, the latter is used whenever a call is not inlined.
2) Looking at your code, I don't see why SDCC wouldn't inline it. AFAIK, SDCC should always inline a function declared inline, unless it has variable arguments (or the call is through a function pointer).
I've looked into this. Since this correct from the pespective of the standard, we don't have a bug here. SDCC currently can't inline the call if the function is more complex than just a function name. I can see that this can be a performance issue, but that would make this a feature request, not a bug report. I'll move it accordingly.
However, there is a workaround to make current SDCC inline the call:
Ticket moved from /p/sdcc/bugs/3271/
Can't be converted: