The clang compiler behaves very aggressively when optimizing some functions. So much so that it in fact breaks our mocking (or any LD preloading for that matter). For instance, for the following code: int X(void) G_NO_INLINE; int Y(void); int X(void) { return -1; } int Y(void) { if (X() < 0) return -1; return 42; } the following assembler is generated: 0000000000118090 <X>: 118090: b8 ff ff ff ff mov $0xffffffff,%eax 118095: c3 ret 00000000001180a0 <Y>: 1180a0: b8 ff ff ff ff mov $0xffffffff,%eax 1180a5: c3 ret It's clear that Y() does not even attempt to call X(). Therefore, even if we provided an alternative implementation (or anybody else for that matter), it is not even called. Note, this happens only with optimizations enabled, i.e. -O1 and bigger. For -O0 clang does the right thing. Fortunately, it offers a way to disable optimizations on a per-function basis. >From our example, if X() and Y() are written like this: int __attribute__((optnone)) X(void) { return -1; } int __attribute__((optnone)) Y(void) { if (X() < 0) return -1; return 42; } then the expected happen, regardless of optimization setting. Therefore, introduce VIR_OPTNONE macro which sets this attribute when building with clang. Fortunately, other compilers realize that they can not do this optimization for non-static functions and thus VIR_OPTNONE can be empty for them. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/internal.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/internal.h b/src/internal.h index 9dc34a0bf5..cf6f314648 100644 --- a/src/internal.h +++ b/src/internal.h @@ -552,3 +552,23 @@ enum { # define fprintf(fh, ...) g_fprintf(fh, __VA_ARGS__) #endif /* VIR_NO_GLIB_STDIO */ + +/* Ideally, we would not need this. But, we want to work with + * broken compilers. Use this to disable optimizations for a + * function, like this: + * + * int VIR_OPTNONE + * virMyFunction(int arg) + * { + * ... + * } + * + * Do NOT use in the header file as it has no effect there. This + * is intended to be used for functions that (might) call or be + * called from mocked function. + */ +#if defined(__clang__) +# define VIR_OPTNONE __attribute__((optnone)) +#else +# define VIR_OPTNONE +#endif -- 2.39.2