diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg
index c7cd4793ad2..09ecfed83e6 100644
--- a/cfg/gtk.cfg
+++ b/cfg/gtk.cfg
@@ -336,13 +336,13 @@
-
+
g_thread_new
g_thread_try_new
g_thread_unref
g_thread_join
-
+
g_variant_iter_copy
g_variant_iter_new
@@ -8387,9 +8387,52 @@
false
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
-
false
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c
index c28eb483f45..0b1e17e013a 100644
--- a/test/cfg/gtk.c
+++ b/test/cfg/gtk.c
@@ -777,3 +777,57 @@ void g_idle_add_freed_data_test(void)
// TODO cppcheck-suppress deallocuse
g_idle_add(source_func_frees_data, data);
}
+
+static gpointer thread_func(gpointer data)
+{
+ return data;
+}
+
+void g_thread_join_releases_thread_test(void)
+{
+ GThread *thread = g_thread_new("test", thread_func, NULL);
+ g_thread_join(thread);
+
+ GThread *thread_try = g_thread_try_new("test", thread_func, NULL, NULL);
+ if (thread_try)
+ g_thread_join(thread_try);
+}
+
+// Creating a thread has side effects, so a thread that is only released is
+// not unused.
+void g_thread_unref_detaches_thread_test(void)
+{
+ GThread *thread = g_thread_new("test", thread_func, NULL);
+ g_thread_unref(thread);
+}
+
+void g_thread_join_parameter_test(GThread *thread)
+{
+ g_thread_join(thread);
+}
+
+// The thread function gets the data as a non-const gpointer.
+void g_thread_data_test(int *data)
+{
+ GThread *thread = g_thread_new("test", thread_func, data);
+ g_thread_join(thread);
+
+ GThread *thread_try = g_thread_try_new("test", thread_func, data, NULL);
+ if (thread_try)
+ g_thread_join(thread_try);
+}
+
+void g_thread_not_joined_test(void)
+{
+ GThread *thread = g_thread_new("test", thread_func, NULL);
+ (void)thread;
+ // cppcheck-suppress resourceLeak
+}
+
+void g_thread_joined_twice_test(void)
+{
+ GThread *thread = g_thread_new("test", thread_func, NULL);
+ g_thread_join(thread);
+ // cppcheck-suppress doubleFree
+ g_thread_join(thread);
+}