On Mon, Apr 28, 2025 at 03:20:56PM +0200, Michal Privoznik via Devel wrote: > From: Michal Privoznik <mpriv...@redhat.com> > > Currently, if we want to mock a function the noinline attribute > is appended after the function (via G_NO_INLINE macro). This used > to work for non pure functions. But there are some trivial > functions (for instance virQEMUCapsProbeHVF()) that are pure, > i.e. have no side effect, and while their call from other parts > of the code is not optimized out, their call from within the same > compilation unit (qemu_capabilities.c) is optimized out. > > This is because inlining and semantic interposition are two > different things. Even GCC's documentation for noinline attribute > [1] states that clearly: > > This function attribute prevents a function from being > considered for inlining. It also disables some other > interprocedural optimizations; it’s preferable to use the more > comprehensive noipa attribute instead if that is your goal. > > Even if a function is declared with the noinline attribute, > there are optimizations other than inlining that can cause > calls to be optimized away if it does not have side effects, > although the function call is live. > > Unfortunately, despite attempts [2] Clang still does not support > the attribute and thus we have to rely on noinline + > -fsemantic-interposition combo. > > 1: > https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute > 2: https://reviews.llvm.org/D101011 > > Signed-off-by: Michal Privoznik <mpriv...@redhat.com> > --- > docs/coding-style.rst | 2 +- > scripts/cocci-macro-file.h | 1 + > src/internal.h | 21 +++++++++++++++++++++ > 3 files changed, 23 insertions(+), 1 deletion(-) > > diff --git a/docs/coding-style.rst b/docs/coding-style.rst > index fe5fe9a906..81382f11d4 100644 > --- a/docs/coding-style.rst > +++ b/docs/coding-style.rst > @@ -633,7 +633,7 @@ analysis tools understand the code better: > ``G_GNUC_FALLTHROUGH`` > allow code reuse by multiple switch cases > > -``G_NO_INLINE`` > +``ATTRIBUTE_NOIPA`` > the function is mocked in the test suite > > ``G_GNUC_NORETURN`` > diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h > index c3112663d1..b26018c20b 100644 > --- a/scripts/cocci-macro-file.h > +++ b/scripts/cocci-macro-file.h > @@ -21,6 +21,7 @@ > > #pragma once > > +#define ATTRIBUTE_NOIPA > #define ATTRIBUTE_NONNULL(x) > #define ATTRIBUTE_PACKED > > diff --git a/src/internal.h b/src/internal.h > index 20aa9b1d41..b96661249e 100644 > --- a/src/internal.h > +++ b/src/internal.h > @@ -177,6 +177,27 @@ > # endif > #endif > > +/** > + * > + * ATTRIBUTE_NOIPA > + * > + * Force compiler to disable interprocedural optimizations between the > + * function with this attribute and its callers. This implies noinline > + * attribute and some others and allows us to mock functions even if > + * they are pure. > + * > + * WARNING: on compilers which don't support the attribute (clang) this > + * is silently declared as noinline which in combination with > + * -fsemantic-interposition option does roughly the same. > + */ > +#ifndef ATTRIBUTE_NOIPA > +# if defined(__has_attribute) && __has_attribute(noipa) > +# define ATTRIBUTE_NOIPA __attribute__((noipa)) > +# else > +# define ATTRIBUTE_NOIPA G_NO_INLINE
Hmm, that's kinda misleading. How about we detach our naming from the impl choice ? ATTRIBUTE_MOCKABLE ? With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|