On Tue, Apr 29, 2025 at 10:31:41AM +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             | 22 ++++++++++++++++++++++
>  3 files changed, 24 insertions(+), 1 deletion(-)

Reviewed-by: Daniel P. Berrangé <berra...@redhat.com>


> +/**
> + *
> + * ATTRIBUTE_MOCKABLE
> + *
> + * Force compiler to disable interprocedural optimizations between the
> + * function with this attribute and its callers. On compilers that
> + * support it (gcc), this expands to noipa attribute which implies
> + * noinline attribute and some others and allows us to mock functions
> + * even if they are pure.
> + *
> + * On compilers which don't support the noipa attribute (clang) this
> + * expands to noinline attribute which in combination with

                                                         ^^^ 'with the'

> + * -fsemantic-interposition option does roughly the same.

                                    ^^^ '(set from meson.build)"

> + */
> +#ifndef ATTRIBUTE_MOCKABLE
> +# if defined(__has_attribute) && __has_attribute(noipa)
> +#  define ATTRIBUTE_MOCKABLE __attribute__((noipa))
> +# else
> +#  define ATTRIBUTE_MOCKABLE G_NO_INLINE
> +# endif
> +#endif
> +
>  #define VIR_WARNINGS_NO_CAST_ALIGN \
>      _Pragma ("GCC diagnostic push") \
>      _Pragma ("GCC diagnostic ignored \"-Wcast-align\"")
> -- 
> 2.49.0
> 

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 :|

Reply via email to