From 44dd2c6e861316d26a78848eb0f6b35bd3b82d4b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 3 Nov 2014 18:23:28 +0100 Subject: util: introduce negative_errno() Imagine a constructor like this: int object_new(void **out) { void *my_object; int r; ... r = ioctl(...); if (r < 0) return -errno; ... *out = my_object; return 0; } We have a lot of those in systemd. If you now call those, gcc might inline the call and optimize it. However, gcc cannot know that "errno" is negative if "r" is. Therefore, a caller like this will produce warnings: r = object_new(&obj); if (r < 0) return r; obj->xyz = "foobar"; In case the ioctl in the constructor fails, gcc might assume "errno" is 0 and thus the error-handling is not triggered. Therefore, "obj" is uninitialized, but accessed. Gcc will warn about that. The new negative_errno() helper can be used to mitigate those warnings. The helper is guaranteed to return a negative integer. Furthermore, it spills out runtime warnings if "errno" is non-negative. Instead of returning "-errno", you can use: return negative_errno(); gcc will no longer assume that this can return >=0, thus, it will not warn about it. Use this new helper in libsystemd-terminal to fix some grdev-drm warnings. --- src/libsystemd-terminal/grdev-drm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libsystemd-terminal/grdev-drm.c') diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c index dba6db2691..48f8e9ce96 100644 --- a/src/libsystemd-terminal/grdev-drm.c +++ b/src/libsystemd-terminal/grdev-drm.c @@ -1393,7 +1393,7 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_ r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); if (r < 0) { - r = -errno; + r = negative_errno(); log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m", card->base.name, fb->base.width, fb->base.height); return r; @@ -1407,7 +1407,7 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_ r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb); if (r < 0) { - r = -errno; + r = negative_errno(); log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m", card->base.name, fb->base.width, fb->base.height); return r; @@ -1415,7 +1415,7 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_ fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset); if (fb->base.maps[0] == MAP_FAILED) { - r = -errno; + r = negative_errno(); log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m", card->base.name, fb->base.width, fb->base.height); return r; @@ -1433,7 +1433,7 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_ r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb); if (r < 0) { - r = -errno; + r = negative_errno(); log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m", card->base.name, fb->base.width, fb->base.height); return r; -- cgit v1.2.3-54-g00ecf