diff options
author | Thomas Haller <thaller@redhat.com> | 2018-09-27 14:20:02 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-10-04 10:58:50 +0200 |
commit | 8eab707481398bfb8aed5fec8e362f6365187b01 (patch) | |
tree | 6317f7438acfa37f934222d988f8ab251ff90cc3 | |
parent | 0b37c236c4bafacce8195ae3d9d6b93ea944e69f (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.h | 10 | ||||
-rw-r--r-- | shared/nm-utils/nm-secret-utils.h | 2 |
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: * |