[PATCH 0/3] Preper noipa attribute over noinline

Somewhat green-ish pipeline: https://gitlab.com/MichalPrivoznik/libvirt/-/pipelines/1790043585 Jobs that failed are unrelated. Thing is, our upstream pipeline started failing on Rawhide + gcc because of IPA. The unfortunate part is, noinline does not guarantee the function is mockable. The fortunate part is, GCC has noipa attribute which is even advocated for in its documentation. Given we are after the freeze and this is potentially hazardous, I'm okay if this is merged after the release. Michal Prívozník (3): internal: Introduce ATTRIBUTE_NOIPA src: s/G_NO_INLINE/ATTRIBUTE_NOIPA/ scripts: Adapt mock-noinline.py to ATTRIBUTE_NOIPA build-aux/syntax-check.mk | 4 ++-- docs/coding-style.rst | 2 +- scripts/cocci-macro-file.h | 1 + scripts/meson.build | 2 +- scripts/{mock-noinline.py => mock-noipa.py} | 6 +++--- src/cpu/cpu.h | 2 +- src/hypervisor/domain_interface.h | 2 +- src/internal.h | 21 +++++++++++++++++++++ src/libxl/libxl_capabilities.h | 2 +- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_capspriv.h | 2 +- src/qemu/qemu_command.h | 6 +++--- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_hotplug.h | 2 +- src/qemu/qemu_interface.h | 2 +- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.h | 2 +- src/qemu/qemu_monitor_priv.h | 2 +- src/qemu/qemu_process.h | 6 +++--- src/rpc/virnetsocket.h | 4 ++-- src/util/vircgroupv2devices.h | 2 +- src/util/vircommand.h | 2 +- src/util/virdevmapper.h | 2 +- src/util/virfile.h | 20 ++++++++++---------- src/util/virfirewalld.h | 2 +- src/util/virhashcode.h | 2 +- src/util/virhostcpu.h | 8 ++++---- src/util/virhostmem.h | 2 +- src/util/virhostuptime.h | 2 +- src/util/viridentitypriv.h | 2 +- src/util/virmacaddr.h | 2 +- src/util/virnetdev.h | 12 ++++++------ src/util/virnetdevbandwidth.h | 2 +- src/util/virnetdevip.h | 2 +- src/util/virnetdevmacvlan.h | 2 +- src/util/virnetdevopenvswitch.h | 2 +- src/util/virnetdevtap.h | 6 +++--- src/util/virnuma.h | 18 +++++++++--------- src/util/virpci.h | 2 +- src/util/virprocess.h | 6 +++--- src/util/virrandom.h | 4 ++-- src/util/virscsi.h | 2 +- src/util/virscsivhost.h | 2 +- src/util/virtpm.h | 2 +- src/util/virutil.h | 16 ++++++++-------- src/util/viruuid.h | 4 ++-- 46 files changed, 113 insertions(+), 91 deletions(-) rename scripts/{mock-noinline.py => mock-noipa.py} (93%) -- 2.49.0

From: Michal Privoznik <mprivozn@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-noi... 2: https://reviews.llvm.org/D101011 Signed-off-by: Michal Privoznik <mprivozn@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 +# endif +#endif + #define VIR_WARNINGS_NO_CAST_ALIGN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wcast-align\"") -- 2.49.0

On Mon, Apr 28, 2025 at 03:20:56PM +0200, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@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-noi... 2: https://reviews.llvm.org/D101011
Signed-off-by: Michal Privoznik <mprivozn@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 :|

From: Michal Privoznik <mprivozn@redhat.com> Per change in coding style done in previous commit, ATTRIBUTE_NOIPA should be used instead of G_NO_INLINE for functions that are mocked in our test suite. Do the change. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/cpu/cpu.h | 2 +- src/hypervisor/domain_interface.h | 2 +- src/libxl/libxl_capabilities.h | 2 +- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_capspriv.h | 2 +- src/qemu/qemu_command.h | 6 +++--- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_hotplug.h | 2 +- src/qemu/qemu_interface.h | 2 +- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.h | 2 +- src/qemu/qemu_monitor_priv.h | 2 +- src/qemu/qemu_process.h | 6 +++--- src/rpc/virnetsocket.h | 4 ++-- src/util/vircgroupv2devices.h | 2 +- src/util/vircommand.h | 2 +- src/util/virdevmapper.h | 2 +- src/util/virfile.h | 20 ++++++++++---------- src/util/virfirewalld.h | 2 +- src/util/virhashcode.h | 2 +- src/util/virhostcpu.h | 8 ++++---- src/util/virhostmem.h | 2 +- src/util/virhostuptime.h | 2 +- src/util/viridentitypriv.h | 2 +- src/util/virmacaddr.h | 2 +- src/util/virnetdev.h | 12 ++++++------ src/util/virnetdevbandwidth.h | 2 +- src/util/virnetdevip.h | 2 +- src/util/virnetdevmacvlan.h | 2 +- src/util/virnetdevopenvswitch.h | 2 +- src/util/virnetdevtap.h | 6 +++--- src/util/virnuma.h | 18 +++++++++--------- src/util/virpci.h | 2 +- src/util/virprocess.h | 6 +++--- src/util/virrandom.h | 4 ++-- src/util/virscsi.h | 2 +- src/util/virscsivhost.h | 2 +- src/util/virtpm.h | 2 +- src/util/virutil.h | 16 ++++++++-------- src/util/viruuid.h | 4 ++-- 40 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index fc6a812eaa..5c281b11b8 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -233,7 +233,7 @@ virCPUGetHost(virArch arch, virDomainCapsCPUModels *models); virCPUDef * -virCPUProbeHost(virArch arch) G_NO_INLINE; +virCPUProbeHost(virArch arch) ATTRIBUTE_NOIPA; virCPUDef * virCPUBaseline(virArch arch, diff --git a/src/hypervisor/domain_interface.h b/src/hypervisor/domain_interface.h index b399085f81..2dd5d7165b 100644 --- a/src/hypervisor/domain_interface.h +++ b/src/hypervisor/domain_interface.h @@ -57,4 +57,4 @@ int virDomainInterfaceBridgeConnect(virDomainDef *def, ebtablesContext *ebtables, bool macFilter, const char *bridgeHelperName) - ATTRIBUTE_NONNULL(2) G_NO_INLINE; + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NOIPA; diff --git a/src/libxl/libxl_capabilities.h b/src/libxl/libxl_capabilities.h index fd6332b63e..a0074faf8f 100644 --- a/src/libxl/libxl_capabilities.h +++ b/src/libxl/libxl_capabilities.h @@ -47,4 +47,4 @@ libxlMakeDomainCapabilities(virDomainCaps *domCaps, int libxlDomainGetEmulatorType(const virDomainDef *def) - G_NO_INLINE; + ATTRIBUTE_NOIPA; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index ea7c14daa9..2fb3c9ae93 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -940,10 +940,10 @@ virSGXCapability * virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps); bool -virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE; +virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) ATTRIBUTE_NOIPA; bool -virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE; +virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) ATTRIBUTE_NOIPA; virArch virQEMUCapsArchFromString(const char *arch); const char *virQEMUCapsArchToString(virArch arch); diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h index 06b36d2eb8..96964bbfa0 100644 --- a/src/qemu/qemu_capspriv.h +++ b/src/qemu/qemu_capspriv.h @@ -82,7 +82,7 @@ virQEMUCapsGetCPUModelX86Data(virQEMUCaps *qemuCaps, virCPUDef * virQEMUCapsProbeHostCPU(virArch hostArch, - virDomainCapsCPUModels *models) G_NO_INLINE; + virDomainCapsCPUModels *models) ATTRIBUTE_NOIPA; void virQEMUCapsSetGICCapabilities(virQEMUCaps *qemuCaps, diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 79d4f47690..b45986881a 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -75,7 +75,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath, /* Open a UNIX socket for chardev FD passing */ int qemuOpenChrChardevUNIXSocket(const virDomainChrSourceDef *dev) - G_NO_INLINE; + ATTRIBUTE_NOIPA; virJSONValue * qemuBuildChrDeviceProps(const virDomainDef *vmdef, @@ -270,7 +270,7 @@ int qemuBuildTPMOpenBackendFDs(const char *tpmdev, int *tpmfd, int *cancelfd) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) G_NO_INLINE; + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NOIPA; const char * qemuAudioDriverTypeToString(virDomainAudioType type); @@ -279,4 +279,4 @@ qemuAudioDriverTypeFromString(const char *str); int qemuVDPAConnect(const char *devicepath) - G_NO_INLINE; + ATTRIBUTE_NOIPA; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5326aba281..741edf3682 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5657,7 +5657,7 @@ qemuDomainResetDeviceRemoval(virDomainObj *vm) } -unsigned long long G_NO_INLINE +unsigned long long ATTRIBUTE_NOIPA qemuDomainGetUnplugTimeout(virDomainObj *vm) { if (qemuDomainIsPSeries(vm->def)) diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 8e3a8f769e..0a15351573 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -116,7 +116,7 @@ qemuDomainSetVcpuInternal(virQEMUDriver *driver, bool state); unsigned long long -qemuDomainGetUnplugTimeout(virDomainObj *vm) G_NO_INLINE; +qemuDomainGetUnplugTimeout(virDomainObj *vm) ATTRIBUTE_NOIPA; int qemuHotplugAttachDBusVMState(virQEMUDriver *driver, diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h index ade02c7386..56a7994957 100644 --- a/src/qemu/qemu_interface.h +++ b/src/qemu/qemu_interface.h @@ -33,7 +33,7 @@ int qemuInterfaceDirectConnect(virDomainDef *def, virNetDevVPortProfileOp vmop); int qemuInterfaceOpenVhostNet(virDomainObj *def, - virDomainNetDef *net) G_NO_INLINE; + virDomainNetDef *net) ATTRIBUTE_NOIPA; int qemuInterfacePrepareSlirp(virQEMUDriver *driver, virDomainNetDef *net); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 8d49ada114..756d1bae91 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -436,7 +436,7 @@ int qemuMonitorSetLink(qemuMonitor *mon, /* These APIs are for use by the internal Text/JSON monitor impl code only */ char *qemuMonitorNextCommandID(qemuMonitor *mon); int qemuMonitorSend(qemuMonitor *mon, - qemuMonitorMessage *msg) G_NO_INLINE; + qemuMonitorMessage *msg) ATTRIBUTE_NOIPA; int qemuMonitorUpdateVideoMemorySize(qemuMonitor *mon, virDomainVideoDef *video, const char *videoName) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index cec4fb387e..1d4d9fe6b7 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -31,7 +31,7 @@ int qemuMonitorJSONIOProcessLine(qemuMonitor *mon, const char *line, qemuMonitorMessage *msg) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int qemuMonitorJSONIOProcess(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor_priv.h b/src/qemu/qemu_monitor_priv.h index 60a3cedb64..8ed25143ad 100644 --- a/src/qemu/qemu_monitor_priv.h +++ b/src/qemu/qemu_monitor_priv.h @@ -101,4 +101,4 @@ qemuMonitorIOWriteWithFD(qemuMonitor *mon, const char *data, size_t len, int fd) - G_NO_INLINE; + ATTRIBUTE_NOIPA; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 8f7b3f24c4..674f56b3d1 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -132,7 +132,7 @@ int qemuProcessOpenVhostVsock(virDomainVsockDef *vsock); int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, virDomainDeviceDef *dev) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int qemuProcessPrepareHost(virQEMUDriver *driver, @@ -219,9 +219,9 @@ int qemuProcessRefreshBalloonState(virDomainObj *vm, int qemuProcessRefreshDisks(virDomainObj *vm, virDomainAsyncJob asyncJob); -int qemuProcessStartManagedPRDaemon(virDomainObj *vm) G_NO_INLINE; +int qemuProcessStartManagedPRDaemon(virDomainObj *vm) ATTRIBUTE_NOIPA; -void qemuProcessKillManagedPRDaemon(virDomainObj *vm) G_NO_INLINE; +void qemuProcessKillManagedPRDaemon(virDomainObj *vm) ATTRIBUTE_NOIPA; typedef struct _qemuProcessQMP qemuProcessQMP; struct _qemuProcessQMP { diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index fec84ca068..31395de7c5 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -132,10 +132,10 @@ int virNetSocketGetUNIXIdentity(virNetSocket *sock, gid_t *gid, pid_t *pid, unsigned long long *timestamp) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virNetSocketGetSELinuxContext(virNetSocket *sock, char **context) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virNetSocketSetBlocking(virNetSocket *sock, bool blocking); diff --git a/src/util/vircgroupv2devices.h b/src/util/vircgroupv2devices.h index d2d769ba5a..d0b36ca15f 100644 --- a/src/util/vircgroupv2devices.h +++ b/src/util/vircgroupv2devices.h @@ -26,7 +26,7 @@ bool virCgroupV2DevicesAvailable(virCgroup *group) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virCgroupV2DevicesDetectProg(virCgroup *group); diff --git a/src/util/vircommand.h b/src/util/vircommand.h index 9bcdce35b9..27221b3549 100644 --- a/src/util/vircommand.h +++ b/src/util/vircommand.h @@ -62,7 +62,7 @@ typedef enum { void virCommandPassFD(virCommand *cmd, int fd, - unsigned int flags) G_NO_INLINE; + unsigned int flags) ATTRIBUTE_NOIPA; void virCommandSetPidFile(virCommand *cmd, const char *pidfile) ATTRIBUTE_NONNULL(2); diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h index 6972050bc5..76400774db 100644 --- a/src/util/virdevmapper.h +++ b/src/util/virdevmapper.h @@ -24,7 +24,7 @@ int virDevMapperGetTargets(const char *path, - GSList **devPaths) G_NO_INLINE; + GSList **devPaths) ATTRIBUTE_NOIPA; bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); diff --git a/src/util/virfile.h b/src/util/virfile.h index e760724037..b57a68ff07 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -124,9 +124,9 @@ int virFileWrapperFdClose(virFileWrapperFd *dfd); void virFileWrapperFdFree(virFileWrapperFd *dfd); int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForLock) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virFileUnlock(int fd, off_t start, off_t len) - G_NO_INLINE; + ATTRIBUTE_NOIPA; typedef int (*virFileRewriteFunc)(int fd, const char *path, @@ -193,10 +193,10 @@ int virFileIsLink(const char *linkpath) ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT; char *virFindFileInPath(const char *file) - G_NO_INLINE; + ATTRIBUTE_NOIPA; char *virFindFileInPathFull(const char *file, const char *const *extraDirs) - G_NO_INLINE; + ATTRIBUTE_NOIPA; char *virFileFindResource(const char *filename, const char *builddir, @@ -215,7 +215,7 @@ void virFileActivateDirOverrideForLib(void); off_t virFileLength(const char *path, int fd) ATTRIBUTE_NONNULL(1); bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); -bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1) G_NO_INLINE; +bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NOIPA; bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); bool virFileIsRegular(const char *file) ATTRIBUTE_NONNULL(1); @@ -254,7 +254,7 @@ int virFileGetMountReverseSubtree(const char *mtabpath, size_t *nmountsret) G_GNUC_WARN_UNUSED_RESULT; char *virFileSanitizePath(const char *path); -char *virFileCanonicalizePath(const char *path) G_NO_INLINE; +char *virFileCanonicalizePath(const char *path) ATTRIBUTE_NOIPA; enum { VIR_FILE_OPEN_NONE = 0, @@ -376,21 +376,21 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFileWrapperFd, virFileWrapperFdFree); int virFileGetXAttr(const char *path, const char *name, char **value) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virFileGetXAttrQuiet(const char *path, const char *name, char **value) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virFileSetXAttr(const char *path, const char *name, const char *value) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virFileRemoveXAttr(const char *path, const char *name) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virFileDataSync(int fd); diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h index 2c7d3e22cd..1e26daef8a 100644 --- a/src/util/virfirewalld.h +++ b/src/util/virfirewalld.h @@ -33,7 +33,7 @@ typedef enum { int virFirewallDGetVersion(unsigned long long *version); int virFirewallDGetBackend(void); -int virFirewallDIsRegistered(void) G_NO_INLINE; +int virFirewallDIsRegistered(void) ATTRIBUTE_NOIPA; int virFirewallDGetZones(char ***zones, size_t *nzones); int virFirewallDGetPolicies(char ***policies, size_t *npolicies); bool virFirewallDZoneExists(const char *match); diff --git a/src/util/virhashcode.h b/src/util/virhashcode.h index 5c68e5a89a..874b779c7f 100644 --- a/src/util/virhashcode.h +++ b/src/util/virhashcode.h @@ -30,4 +30,4 @@ #include "internal.h" uint32_t virHashCodeGen(const void *key, size_t len, uint32_t seed) - G_NO_INLINE; + ATTRIBUTE_NOIPA; diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h index 92db35232b..1093104698 100644 --- a/src/util/virhostcpu.h +++ b/src/util/virhostcpu.h @@ -46,7 +46,7 @@ virBitmap *virHostCPUGetAvailableCPUsBitmap(void); int virHostCPUGetIsolated(virBitmap **isolated); int virHostCPUGetCount(void); -int virHostCPUGetThreadsPerSubcore(virArch arch) G_NO_INLINE; +int virHostCPUGetThreadsPerSubcore(virArch arch) ATTRIBUTE_NOIPA; int virHostCPUGetMap(unsigned char **cpumap, unsigned int *online, @@ -60,7 +60,7 @@ int virHostCPUGetInfo(virArch hostarch, unsigned int *threads); -int virHostCPUGetKVMMaxVCPUs(void) G_NO_INLINE; +int virHostCPUGetKVMMaxVCPUs(void) ATTRIBUTE_NOIPA; int virHostCPUStatsAssign(virNodeCPUStatsPtr param, const char *name, @@ -78,7 +78,7 @@ virBitmap *virHostCPUGetSiblingsList(unsigned int cpu); int virHostCPUGetOnline(unsigned int cpu, bool *online); unsigned int -virHostCPUGetMicrocodeVersion(virArch hostArch) G_NO_INLINE; +virHostCPUGetMicrocodeVersion(virArch hostArch) ATTRIBUTE_NOIPA; int virHostCPUGetMSR(unsigned long index, uint64_t *msr); @@ -90,7 +90,7 @@ virHostCPUTscInfo *virHostCPUGetTscInfo(void); int virHostCPUGetSignature(char **signature); int virHostCPUGetPhysAddrSize(const virArch hostArch, - unsigned int *size) G_NO_INLINE; + unsigned int *size) ATTRIBUTE_NOIPA; int virHostCPUGetHaltPollTime(pid_t pid, unsigned long long *haltPollSuccess, diff --git a/src/util/virhostmem.h b/src/util/virhostmem.h index 79e1a300a8..43098ff827 100644 --- a/src/util/virhostmem.h +++ b/src/util/virhostmem.h @@ -57,4 +57,4 @@ int virHostMemAllocPages(unsigned int npages, bool add); int virHostMemGetTHPSize(unsigned long long *size) - G_NO_INLINE; + ATTRIBUTE_NOIPA; diff --git a/src/util/virhostuptime.h b/src/util/virhostuptime.h index 44a91b5b52..f7a13985d6 100644 --- a/src/util/virhostuptime.h +++ b/src/util/virhostuptime.h @@ -24,7 +24,7 @@ int virHostGetBootTime(unsigned long long *when) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virHostBootTimeInit(void); diff --git a/src/util/viridentitypriv.h b/src/util/viridentitypriv.h index 63357d891a..b6308848f1 100644 --- a/src/util/viridentitypriv.h +++ b/src/util/viridentitypriv.h @@ -27,4 +27,4 @@ #include "viridentity.h" char * -virIdentityEnsureSystemToken(void) G_NO_INLINE; +virIdentityEnsureSystemToken(void) ATTRIBUTE_NOIPA; diff --git a/src/util/virmacaddr.h b/src/util/virmacaddr.h index 7b9eb7443b..6acfbe2c8b 100644 --- a/src/util/virmacaddr.h +++ b/src/util/virmacaddr.h @@ -49,7 +49,7 @@ void virMacAddrGetRaw(const virMacAddr *src, unsigned char dst[VIR_MAC_BUFLEN]); const char *virMacAddrFormat(const virMacAddr *addr, char *str); void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN], - virMacAddr *addr) G_NO_INLINE; + virMacAddr *addr) ATTRIBUTE_NOIPA; int virMacAddrParse(const char* str, virMacAddr *addr) G_GNUC_WARN_UNUSED_RESULT; int virMacAddrParseHex(const char* str, diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 99fe761c1d..02681616f2 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -168,11 +168,11 @@ int virNetDevSetupControl(const char *ifname, G_GNUC_WARN_UNUSED_RESULT; int virNetDevExists(const char *brname) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevSetOnline(const char *ifname, bool online) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevGetOnline(const char *ifname, bool *online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; @@ -180,7 +180,7 @@ int virNetDevGetOnline(const char *ifname, int virNetDevSetMAC(const char *ifname, const virMacAddr *macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevGetMAC(const char *ifname, virMacAddr *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; @@ -192,7 +192,7 @@ int virNetDevSetCoalesce(const char *ifname, int virNetDevSetMTU(const char *ifname, int mtu) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevSetMTUFromDevice(const char *ifname, const char *otherifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; @@ -314,10 +314,10 @@ int virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, const char *file) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevRunEthernetScript(const char *ifname, const char *script) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virNetDevVFInterfaceStats(virPCIDeviceAddress *vfAddr, virDomainInterfaceStatsPtr stats) diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h index 65c1500637..a89cf0e6ba 100644 --- a/src/util/virnetdevbandwidth.h +++ b/src/util/virnetdevbandwidth.h @@ -83,7 +83,7 @@ int virNetDevBandwidthUpdateFilter(const char *ifname, int virNetDevBandwidthSetRootQDisc(const char *ifname, const char *qdisc) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname, bool hierarchical_class); diff --git a/src/util/virnetdevip.h b/src/util/virnetdevip.h index fdf116f509..21a0fda97d 100644 --- a/src/util/virnetdevip.h +++ b/src/util/virnetdevip.h @@ -59,7 +59,7 @@ int virNetDevIPAddrAdd(const char *ifname, virSocketAddr *addr, virSocketAddr *peer, unsigned int prefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevIPRouteAdd(const char *ifname, virSocketAddr *addr, unsigned int prefix, diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h index a5c34d6417..64b2f48952 100644 --- a/src/util/virnetdevmacvlan.h +++ b/src/util/virnetdevmacvlan.h @@ -47,7 +47,7 @@ typedef enum { } virNetDevMacVLanCreateFlags; bool virNetDevMacVLanIsMacvtap(const char *ifname) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevMacVLanCreate(const char *ifname, const virMacAddr *macaddress, diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index a20fb5b029..d6a5a9b788 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -65,7 +65,7 @@ virNetDevOpenvswitchMaybeUnescapeReply(char *reply) int virNetDevOpenvswitchGetVhostuserIfname(const char *path, bool server, char **ifname) - ATTRIBUTE_NONNULL(3) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(3) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevOpenvswitchUpdateVlan(const char *ifname, const virNetDevVlan *virtVlan) diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h index 9ebe0ee9ed..9fb7badb41 100644 --- a/src/util/virnetdevtap.h +++ b/src/util/virnetdevtap.h @@ -34,7 +34,7 @@ int virNetDevTapCreate(char **ifname, int *tapfd, size_t tapfdSize, unsigned int flags) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevTapDelete(const char *ifname, const char *tunpath) @@ -44,7 +44,7 @@ int virNetDevTapGetName(int tapfd, char **ifname) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; char* virNetDevTapGetRealDeviceName(char *ifname) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; typedef enum { VIR_NETDEV_TAP_CREATE_NONE = 0, @@ -102,7 +102,7 @@ int virNetDevTapCreateInBridgePort(const char *brname, unsigned int *actualMTU, unsigned int flags) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virNetDevTapInterfaceStats(const char *ifname, virDomainInterfaceStatsPtr stats, diff --git a/src/util/virnuma.h b/src/util/virnuma.h index 475df96e1d..70cf701f51 100644 --- a/src/util/virnuma.h +++ b/src/util/virnuma.h @@ -33,20 +33,20 @@ int virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode, virBitmap *virNumaGetHostMemoryNodeset(void); bool virNumaNodesetIsAvailable(virBitmap *nodeset); -bool virNumaIsAvailable(void) G_NO_INLINE; -int virNumaGetMaxNode(void) G_NO_INLINE; -bool virNumaNodeIsAvailable(int node) G_NO_INLINE; +bool virNumaIsAvailable(void) ATTRIBUTE_NOIPA; +int virNumaGetMaxNode(void) ATTRIBUTE_NOIPA; +bool virNumaNodeIsAvailable(int node) ATTRIBUTE_NOIPA; int virNumaGetDistances(int node, int **distances, - int *ndistances) G_NO_INLINE; + int *ndistances) ATTRIBUTE_NOIPA; int virNumaGetNodeMemory(int node, unsigned long long *memsize, - unsigned long long *memfree) G_NO_INLINE; + unsigned long long *memfree) ATTRIBUTE_NOIPA; -unsigned int virNumaGetMaxCPUs(void) G_NO_INLINE; +unsigned int virNumaGetMaxCPUs(void) ATTRIBUTE_NOIPA; -int virNumaGetNodeOfCPU(int cpu) G_NO_INLINE; -int virNumaGetNodeCPUs(int node, virBitmap **cpus) G_NO_INLINE; +int virNumaGetNodeOfCPU(int cpu) ATTRIBUTE_NOIPA; +int virNumaGetNodeCPUs(int node, virBitmap **cpus) ATTRIBUTE_NOIPA; int virNumaCPUSetToNodeset(virBitmap *cpuset, virBitmap **nodeset); int virNumaNodesetToCPUset(virBitmap *nodeset, @@ -62,7 +62,7 @@ int virNumaGetPages(int node, unsigned long long **pages_avail, unsigned long long **pages_free, size_t *npages) - ATTRIBUTE_NONNULL(5) G_NO_INLINE; + ATTRIBUTE_NONNULL(5) ATTRIBUTE_NOIPA; int virNumaSetPagePoolSize(int node, unsigned int page_size, unsigned long long page_count, diff --git a/src/util/virpci.h b/src/util/virpci.h index 4409864057..2b69ed2807 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -124,7 +124,7 @@ int virPCIDeviceReset(virPCIDevice *dev, virPCIDeviceList *activeDevs, virPCIDeviceList *inactiveDevs); -int virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev, char **moduleName) G_NO_INLINE; +int virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev, char **moduleName) ATTRIBUTE_NOIPA; void virPCIDeviceSetManaged(virPCIDevice *dev, bool managed); diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 9c74ec7e35..43f8777dae 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -77,13 +77,13 @@ void virProcessGetNamespaces(pid_t pid, int virProcessSetNamespaces(size_t nfdlist, int *fdlist); -int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes) G_NO_INLINE; +int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes) ATTRIBUTE_NOIPA; int virProcessSetMaxProcesses(pid_t pid, unsigned int procs); int virProcessSetMaxFiles(pid_t pid, unsigned int files); int virProcessSetMaxCoreSize(pid_t pid, unsigned long long bytes); void virProcessActivateMaxFiles(void); -int virProcessGetMaxMemLock(pid_t pid, unsigned long long *bytes) G_NO_INLINE; +int virProcessGetMaxMemLock(pid_t pid, unsigned long long *bytes) ATTRIBUTE_NOIPA; /* Callback to run code within the mount namespace tied to the given * pid. This function must use only async-signal-safe functions, as @@ -111,7 +111,7 @@ typedef int (*virProcessForkCallback)(pid_t ppid, int virProcessRunInFork(virProcessForkCallback cb, void *opaque) - G_NO_INLINE; + ATTRIBUTE_NOIPA; int virProcessSetupPrivateMountNS(void); diff --git a/src/util/virrandom.h b/src/util/virrandom.h index 3bc7d8889c..1b29722fb6 100644 --- a/src/util/virrandom.h +++ b/src/util/virrandom.h @@ -20,10 +20,10 @@ #include "internal.h" -uint64_t virRandomBits(int nbits) G_NO_INLINE; +uint64_t virRandomBits(int nbits) ATTRIBUTE_NOIPA; double virRandom(void); uint32_t virRandomInt(uint32_t max); int virRandomBytes(unsigned char *buf, size_t buflen) - ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_NO_INLINE; + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NOIPA; int virRandomGenerateWWN(char **wwn, const char *virt_type); char *virRandomToken(size_t len); diff --git a/src/util/virscsi.h b/src/util/virscsi.h index 8d7c00160b..016a0a79f6 100644 --- a/src/util/virscsi.h +++ b/src/util/virscsi.h @@ -34,7 +34,7 @@ char *virSCSIDeviceGetSgName(const char *sysfs_prefix, const char *adapter, unsigned int bus, unsigned int target, - unsigned long long unit) G_NO_INLINE; + unsigned long long unit) ATTRIBUTE_NOIPA; char *virSCSIDeviceGetDevName(const char *sysfs_prefix, const char *adapter, unsigned int bus, diff --git a/src/util/virscsivhost.h b/src/util/virscsivhost.h index 48b5fdec78..13294b53dd 100644 --- a/src/util/virscsivhost.h +++ b/src/util/virscsivhost.h @@ -57,6 +57,6 @@ void virSCSIVHostDeviceGetUsedBy(virSCSIVHostDevice *dev, const char **drv_name, const char **dom_name); void virSCSIVHostDeviceFree(virSCSIVHostDevice *dev); -int virSCSIVHostOpenVhostSCSI(int *vhostfd) G_NO_INLINE; +int virSCSIVHostOpenVhostSCSI(int *vhostfd) ATTRIBUTE_NOIPA; G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSCSIVHostDevice, virSCSIVHostDeviceFree); diff --git a/src/util/virtpm.h b/src/util/virtpm.h index c741d28465..4548683361 100644 --- a/src/util/virtpm.h +++ b/src/util/virtpm.h @@ -20,7 +20,7 @@ #pragma once -char *virTPMCreateCancelPath(const char *devpath) G_NO_INLINE; +char *virTPMCreateCancelPath(const char *devpath) ATTRIBUTE_NOIPA; char *virTPMGetSwtpm(void); char *virTPMGetSwtpmSetup(void); diff --git a/src/util/virutil.h b/src/util/virutil.h index 3bac15d02b..4a059fdfe0 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -89,17 +89,17 @@ static inline int pthread_sigmask(int how, } #endif -char *virGetHostname(void) G_NO_INLINE; +char *virGetHostname(void) ATTRIBUTE_NOIPA; char *virGetHostnameQuiet(void); char *virGetUserDirectory(void); char *virGetUserDirectoryByUID(uid_t uid); char *virGetUserConfigDirectory(void); char *virGetUserCacheDirectory(void); -char *virGetUserRuntimeDirectory(void) G_NO_INLINE; +char *virGetUserRuntimeDirectory(void) ATTRIBUTE_NOIPA; char *virGetUserShell(uid_t uid); -char *virGetUserName(uid_t uid) G_NO_INLINE; -char *virGetGroupName(gid_t gid) G_NO_INLINE; +char *virGetUserName(uid_t uid) ATTRIBUTE_NOIPA; +char *virGetGroupName(gid_t gid) ATTRIBUTE_NOIPA; int virGetGroupList(uid_t uid, gid_t group, gid_t **groups) ATTRIBUTE_NONNULL(3); @@ -131,16 +131,16 @@ int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr); time_t virGetSelfLastChanged(void); void virUpdateSelfLastChanged(const char *path); -long virGetSystemPageSize(void) G_NO_INLINE; -long virGetSystemPageSizeKB(void) G_NO_INLINE; +long virGetSystemPageSize(void) ATTRIBUTE_NOIPA; +long virGetSystemPageSizeKB(void) ATTRIBUTE_NOIPA; unsigned long long virMemoryLimitTruncate(unsigned long long value); bool virMemoryLimitIsSet(unsigned long long value); -unsigned long long virMemoryMaxValue(bool ulong) G_NO_INLINE; +unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOIPA; bool virHostHasIOMMU(void); -char *virHostGetDRMRenderNode(void) G_NO_INLINE; +char *virHostGetDRMRenderNode(void) ATTRIBUTE_NOIPA; /* Kernel cmdline match and comparison strategy for arg=value pairs */ typedef enum { diff --git a/src/util/viruuid.h b/src/util/viruuid.h index 9667bd3200..250d18abab 100644 --- a/src/util/viruuid.h +++ b/src/util/viruuid.h @@ -41,11 +41,11 @@ int virSetHostUUIDStr(const char *host_uuid); -int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1) G_NO_INLINE; +int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NOIPA; bool virUUIDIsValid(const unsigned char *uuid); -int virUUIDGenerate(unsigned char *uuid) G_NO_INLINE; +int virUUIDGenerate(unsigned char *uuid) ATTRIBUTE_NOIPA; int virUUIDParse(const char *uuidstr, unsigned char *uuid) -- 2.49.0

From: Michal Privoznik <mprivozn@redhat.com> The script is renamed to mock-noipa.py and adjusted to check for the new attribute. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- build-aux/syntax-check.mk | 4 ++-- scripts/meson.build | 2 +- scripts/{mock-noinline.py => mock-noipa.py} | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename scripts/{mock-noinline.py => mock-noipa.py} (93%) diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk index d414e033df..16a28241db 100644 --- a/build-aux/syntax-check.mk +++ b/build-aux/syntax-check.mk @@ -1326,9 +1326,9 @@ sc_spacing-check: $(PERL) $(top_srcdir)/build-aux/check-spacing.pl || \ { echo 'incorrect formatting' 1>&2; exit 1; } -sc_mock-noinline: +sc_mock-noipa: $(AM_V_GEN)$(VC_LIST_EXCEPT) | $(GREP) '\.[ch]$$' | $(RUNUTF8) \ - $(PYTHON) $(top_srcdir)/scripts/mock-noinline.py + $(PYTHON) $(top_srcdir)/scripts/mock-noipa.py sc_header-ifdef: $(AM_V_GEN)$(VC_LIST_EXCEPT) | $(GREP) '\.[h]$$' | $(RUNUTF8) xargs \ diff --git a/scripts/meson.build b/scripts/meson.build index 2798e302ab..bc38277dbf 100644 --- a/scripts/meson.build +++ b/scripts/meson.build @@ -29,7 +29,7 @@ scripts = [ 'meson-install-web.py', 'meson-python.sh', 'meson-timestamp.py', - 'mock-noinline.py', + 'mock-noipa.py', 'prohibit-duplicate-header.py', 'qemu-replies-tool.py', ] diff --git a/scripts/mock-noinline.py b/scripts/mock-noipa.py similarity index 93% rename from scripts/mock-noinline.py rename to scripts/mock-noipa.py index 77a5ca23e2..66a5f38bdc 100755 --- a/scripts/mock-noinline.py +++ b/scripts/mock-noipa.py @@ -22,7 +22,7 @@ import sys noninlined = {} mocked = {} -# Functions in public header don't get the noinline annotation +# Functions in public header don't get the noipa annotation noninlined["virEventAddTimeout"] = True # This one confuses the script as its defined in the mock file # but is actually just a local helper @@ -43,7 +43,7 @@ def scan_annotations(filename): elif line.isspace(): func = None - if "G_NO_INLINE" in line: + if "ATTRIBUTE_NOIPA" in line: if func is not None: noninlined[func] = True @@ -74,7 +74,7 @@ warned = False for func in mocked.keys(): if func not in noninlined: warned = True - print("%s is mocked at %s but missing 'G_NO_INLINE' annotation" % + print("%s is mocked at %s but missing 'ATTRIBUTE_NOIPA' annotation" % (func, mocked[func]), file=sys.stderr) if warned: -- 2.49.0

On Mon, Apr 28, 2025 at 03:20:55PM +0200, Michal Privoznik via Devel wrote:
Somewhat green-ish pipeline:
https://gitlab.com/MichalPrivoznik/libvirt/-/pipelines/1790043585
Jobs that failed are unrelated.
Thing is, our upstream pipeline started failing on Rawhide + gcc because of IPA. The unfortunate part is, noinline does not guarantee the function is mockable. The fortunate part is, GCC has noipa attribute which is even advocated for in its documentation.
Took a while to dig into history of this, as I know we debated noipa in the past. AFAICT, we decided NOT to use noipa solely because it was a GCC only solution, but despite that, we ended up having to use add a CLang-only solution anyway in the form of -fsemantic-interposition. Given the latter, and that we have long known 'noinline' was insufficient, it makes sense to finally use 'noipa' on GCC.
Given we are after the freeze and this is potentially hazardous, I'm okay if this is merged after the release.
Yeah, probably best to wait until next cycle, as we've got a long history of unexpected edge cases with mocking & interactions with compiler optimization. Would be good to have a cycle to debug any possible fallout. 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 :|
participants (2)
-
Daniel P. Berrangé
-
Michal Privoznik