summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-09-27 14:20:02 +0200
committerThomas Haller <thaller@redhat.com>2018-10-04 10:58:50 +0200
commit8eab707481398bfb8aed5fec8e362f6365187b01 (patch)
tree6317f7438acfa37f934222d988f8ab251ff90cc3
parent0b37c236c4bafacce8195ae3d9d6b93ea944e69f (diff)
shared: avoid invoking g_free() with NULL from gs_free cleanup attribute
In general, it's fine to pass %NULL to g_free(). However, consider: char * foo (void) { gs_free char *value = NULL; value = g_strdup ("hi"); return g_steal_pointer (&value); } gs_free, gs_local_free(), and g_steal_pointer() are all inlinable. Here the compiler can easily recognize that we always pass %NULL to g_free(). But with the previous implementation, the compiler would not omit the call to g_free(). Similar patterns happen all over the place: gboolean baz (void) { gs_free char *value = NULL; if (!some_check ()) return FALSE; value = get_value (); if (!value) return FALSE; return TRUE; } in this example, g_free() is only required after setting @value to non-NULL. Note that this does increase the binary side a bit (4k for libnm, 8k for NetworkManager, with "-O2").
-rw-r--r--shared/nm-utils/nm-macros-internal.h10
-rw-r--r--shared/nm-utils/nm-secret-utils.h2
2 files changed, 6 insertions, 6 deletions
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index b8b945342..d78f08741 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -99,7 +99,7 @@ static inline void name (Type *v) \
* Call g_free() on a variable location when it goes out of scope.
*/
#define gs_free nm_auto(gs_local_free)
-NM_AUTO_DEFINE_FCN_VOID (void *, gs_local_free, g_free)
+NM_AUTO_DEFINE_FCN_VOID0 (void *, gs_local_free, g_free)
/**
* gs_unref_object:
@@ -160,7 +160,7 @@ NM_AUTO_DEFINE_FCN0 (GHashTable *, gs_local_hashtable_unref, g_hash_table_unref)
* of scope.
*/
#define gs_free_slist nm_auto(gs_local_free_slist)
-NM_AUTO_DEFINE_FCN (GSList *, gs_local_free_slist, g_slist_free)
+NM_AUTO_DEFINE_FCN0 (GSList *, gs_local_free_slist, g_slist_free)
/**
* gs_unref_bytes:
@@ -178,7 +178,7 @@ NM_AUTO_DEFINE_FCN0 (GBytes *, gs_local_bytes_unref, g_bytes_unref)
* Call g_strfreev() on a variable location when it goes out of scope.
*/
#define gs_strfreev nm_auto(gs_local_strfreev)
-NM_AUTO_DEFINE_FCN (char **, gs_local_strfreev, g_strfreev)
+NM_AUTO_DEFINE_FCN0 (char **, gs_local_strfreev, g_strfreev)
/**
* gs_free_error:
@@ -222,7 +222,7 @@ static inline int nm_close (int fd);
* However, let's never mix them. To free malloc'ed memory, always use
* free() or nm_auto_free.
*/
-NM_AUTO_DEFINE_FCN_VOID (void *, _nm_auto_free_impl, free)
+NM_AUTO_DEFINE_FCN_VOID0 (void *, _nm_auto_free_impl, free)
#define nm_auto_free nm_auto(_nm_auto_free_impl)
NM_AUTO_DEFINE_FCN0 (GVariantIter *, _nm_auto_free_variant_iter, g_variant_iter_free)
@@ -231,7 +231,7 @@ NM_AUTO_DEFINE_FCN0 (GVariantIter *, _nm_auto_free_variant_iter, g_variant_iter_
NM_AUTO_DEFINE_FCN0 (GVariantBuilder *, _nm_auto_unref_variant_builder, g_variant_builder_unref)
#define nm_auto_unref_variant_builder nm_auto(_nm_auto_unref_variant_builder)
-NM_AUTO_DEFINE_FCN (GList *, _nm_auto_free_list, g_list_free)
+NM_AUTO_DEFINE_FCN0 (GList *, _nm_auto_free_list, g_list_free)
#define nm_auto_free_list nm_auto(_nm_auto_free_list)
NM_AUTO_DEFINE_FCN0 (GChecksum *, _nm_auto_checksum_free, g_checksum_free)
diff --git a/shared/nm-utils/nm-secret-utils.h b/shared/nm-utils/nm-secret-utils.h
index 21a3c1ba1..9df31afea 100644
--- a/shared/nm-utils/nm-secret-utils.h
+++ b/shared/nm-utils/nm-secret-utils.h
@@ -43,7 +43,7 @@ nm_free_secret (char *secret)
}
}
-NM_AUTO_DEFINE_FCN (char *, _nm_auto_free_secret, nm_free_secret)
+NM_AUTO_DEFINE_FCN0 (char *, _nm_auto_free_secret, nm_free_secret)
/**
* nm_auto_free_secret:
*