mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-08 18:36:17 +01:00
gmem: Only evaluate pointer argument to g_clear_pointer() once
The new typeof() macro version of g_clear_pointer() was evaluating its pointer argument more than once, meaning any side effects would be evaluated multiple times. The existing (other) macro version of g_clear_pointer() was evaluating its argument exactly once. This mismatch could have confused people or lead to subtle bugs. See https://gitlab.gnome.org/GNOME/glib/issues/1494. Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
parent
9a72ebe016
commit
2e9c31af11
@ -114,8 +114,9 @@ gpointer g_try_realloc_n (gpointer mem,
|
|||||||
#define g_clear_pointer(pp, destroy) \
|
#define g_clear_pointer(pp, destroy) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \
|
G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \
|
||||||
__typeof__(*(pp)) _ptr = *(pp); \
|
__typeof__((pp)) _pp = (pp); \
|
||||||
*(pp) = NULL; \
|
__typeof__(*(pp)) _ptr = *_pp; \
|
||||||
|
*_pp = NULL; \
|
||||||
if (_ptr) \
|
if (_ptr) \
|
||||||
(destroy) (_ptr); \
|
(destroy) (_ptr); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
@ -533,6 +533,32 @@ test_clear_pointer_cast (void)
|
|||||||
g_assert_null (hash_table);
|
g_assert_null (hash_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test that the macro version of g_clear_pointer() only evaluates its argument
|
||||||
|
* once, just like the function version would. */
|
||||||
|
static void
|
||||||
|
test_clear_pointer_side_effects (void)
|
||||||
|
{
|
||||||
|
gchar **my_string_array, **i;
|
||||||
|
|
||||||
|
my_string_array = g_new0 (gchar*, 3);
|
||||||
|
my_string_array[0] = g_strdup ("hello");
|
||||||
|
my_string_array[1] = g_strdup ("there");
|
||||||
|
my_string_array[2] = NULL;
|
||||||
|
|
||||||
|
i = my_string_array;
|
||||||
|
|
||||||
|
g_clear_pointer (i++, g_free);
|
||||||
|
|
||||||
|
g_assert_true (i == &my_string_array[1]);
|
||||||
|
g_assert_null (my_string_array[0]);
|
||||||
|
g_assert_nonnull (my_string_array[1]);
|
||||||
|
g_assert_null (my_string_array[2]);
|
||||||
|
|
||||||
|
g_free (my_string_array[1]);
|
||||||
|
g_free (my_string_array[2]);
|
||||||
|
g_free (my_string_array);
|
||||||
|
}
|
||||||
|
|
||||||
static int obj_count;
|
static int obj_count;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -673,6 +699,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
|
g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
|
||||||
g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
|
g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
|
||||||
g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast);
|
g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast);
|
||||||
|
g_test_add_func ("/utils/clear-pointer/side-effects", test_clear_pointer_side_effects);
|
||||||
g_test_add_func ("/utils/take-pointer", test_take_pointer);
|
g_test_add_func ("/utils/take-pointer", test_take_pointer);
|
||||||
g_test_add_func ("/utils/clear-source", test_clear_source);
|
g_test_add_func ("/utils/clear-source", test_clear_source);
|
||||||
g_test_add_func ("/utils/misc-mem", test_misc_mem);
|
g_test_add_func ("/utils/misc-mem", test_misc_mem);
|
||||||
|
Loading…
Reference in New Issue
Block a user