diff options
Diffstat (limited to 'dev-libs/glib/files/glib-2.76.0-g_strdup-c++.patch')
-rw-r--r-- | dev-libs/glib/files/glib-2.76.0-g_strdup-c++.patch | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/dev-libs/glib/files/glib-2.76.0-g_strdup-c++.patch b/dev-libs/glib/files/glib-2.76.0-g_strdup-c++.patch new file mode 100644 index 000000000000..23b0a1b641c1 --- /dev/null +++ b/dev-libs/glib/files/glib-2.76.0-g_strdup-c++.patch @@ -0,0 +1,132 @@ +https://bugs.gentoo.org/901035 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3322 +https://gitlab.gnome.org/GNOME/glib/-/commit/cc7f2f81cc59751fcc689731dcd60af5da5723ba + +From cc7f2f81cc59751fcc689731dcd60af5da5723ba Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao <xry111@xry111.site> +Date: Mon, 13 Mar 2023 16:23:37 +0800 +Subject: [PATCH] gstrfuncs: Improve inline version of g_strdup() to avoid + breaking C++ code + +Wrap the logic into a G_ALWAYS_INLINE function, instead of using a +complex statement-expression which is not allowed in braced initializer +lists and expanded into some bad thing when it's used as +`::g_strdup(...)`. + +We cannot use `__builtin_constant_p (str)` because GCC documentation +clearly states that it always produces 0 when str is a const char * +argument of an inline function. But `__builtin_constant_p (!str)`, +`__builtin_constant_p (!!str)`, and +`__builtin_constant_p (strlen (str))` functions properly with `-O1` or +above enabled. + +Fixes #2936. +--- a/glib/gstrfuncs.h ++++ b/glib/gstrfuncs.h +@@ -204,23 +204,6 @@ gboolean (g_str_has_prefix) (const gchar *str, + (g_str_has_suffix) (STR, SUFFIX) \ + ) + +-#define g_strdup(STR) \ +- (__builtin_constant_p ((STR)) ? \ +- (G_LIKELY ((STR) != NULL) ? \ +- G_GNUC_EXTENSION ({ \ +- const char *const ___str = ((STR)); \ +- const char *const __str = _G_STR_NONNULL (___str); \ +- const size_t __str_len = strlen (__str) + 1; \ +- char *__dup_str = (char *) g_malloc (__str_len); \ +- (char *) memcpy (__dup_str, __str, __str_len); \ +- }) \ +- : \ +- (char *) (NULL) \ +- ) \ +- : \ +- (g_strdup) ((STR)) \ +- ) +- + #endif /* !defined (__GI_SCANNER__) */ + #endif /* !defined (__GTK_DOC_IGNORE__) */ + #endif /* G_GNUC_CHECK_VERSION (2, 0) */ +@@ -318,6 +301,32 @@ GLIB_AVAILABLE_IN_ALL + gchar* g_strjoin (const gchar *separator, + ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; + ++#if G_GNUC_CHECK_VERSION(2, 0) ++#ifndef __GTK_DOC_IGNORE__ ++#ifndef __GI_SCANNER__ ++ ++G_ALWAYS_INLINE static inline char * ++g_strdup_inline (const char *str) ++{ ++ if (__builtin_constant_p (!str) && !str) ++ return NULL; ++ ++ if (__builtin_constant_p (!!str) && !!str && __builtin_constant_p (strlen (str))) ++ { ++ const size_t len = strlen (str) + 1; ++ char *dup_str = (char *) g_malloc (len); ++ return (char *) memcpy (dup_str, str, len); ++ } ++ ++ return g_strdup (str); ++} ++ ++#define g_strdup(x) g_strdup_inline (x) ++ ++#endif /* !defined (__GI_SCANNER__) */ ++#endif /* !defined (__GTK_DOC_IGNORE__) */ ++#endif /* G_GNUC_CHECK_VERSION (2, 0) */ ++ + /* Make a copy of a string interpreting C string -style escape + * sequences. Inverse of g_strescape. The recognized sequences are \b + * \f \n \r \t \\ \" and the octal format. +--- a/glib/tests/cxx.cpp ++++ b/glib/tests/cxx.cpp +@@ -349,6 +349,36 @@ test_strdup_macro (void) + g_free (str); + } + ++static void ++test_strdup_macro_qualified (void) ++{ ++ gchar *str; ++ ++ g_assert_null (::g_strdup (NULL)); ++ ++ str = ::g_strdup ("C++ is cool too!"); ++ g_assert_nonnull (str); ++ g_assert_cmpstr (str, ==, "C++ is cool too!"); ++ g_free (str); ++} ++ ++static void ++test_strdup_macro_nested_initializer (void) ++{ ++ struct ++ { ++ char *p, *q; ++ } strings = { ++ g_strdup (NULL), ++ g_strdup ("C++ is cool too!"), ++ }; ++ ++ g_assert_null (strings.p); ++ g_assert_nonnull (strings.q); ++ g_assert_cmpstr (strings.q, ==, "C++ is cool too!"); ++ g_free (strings.q); ++} ++ + static void + test_str_has_prefix (void) + { +@@ -527,6 +557,8 @@ main (int argc, char *argv[]) + g_test_add_func ("/C++/str-equal", test_str_equal); + g_test_add_func ("/C++/strdup", test_strdup); + g_test_add_func ("/C++/strdup/macro", test_strdup_macro); ++ g_test_add_func ("/C++/strdup/macro/qualified", test_strdup_macro_qualified); ++ g_test_add_func ("/C++/strdup/macro/nested-initializer", test_strdup_macro_nested_initializer); + g_test_add_func ("/C++/str-has-prefix", test_str_has_prefix); + g_test_add_func ("/C++/str-has-prefix/macro", test_str_has_prefix_macro); + g_test_add_func ("/C++/str-has-suffix", test_str_has_suffix); +-- +GitLab |