glib/gobject/tests/type-flags.c
Alex Richardson 5ecd3cbe52 gobject: use g_once_init_enter_pointer for GType initializers
GType is either an integer or a pointer, so we have to use the _pointer
version here to support architectures such as Morello.

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
See also: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3578
2023-10-04 14:50:54 +01:00

247 lines
7.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: LGPL-2.1-or-later
// SPDX-FileCopyrightText: 2021 Emmanuele Bassi
#include <glib-object.h>
typedef struct
{
GTypeInterface g_iface;
} TestInterfaceInterface;
GType test_interface_get_type (void);
#define TEST_TYPE_INTERFACE test_interface_get_type ()
G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_INVALID)
static void
test_interface_default_init (TestInterfaceInterface *iface)
{
}
static void
test_type_flags_interface (void)
{
g_assert_false (G_TYPE_IS_ABSTRACT (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_ABSTRACT));
g_assert_false (G_TYPE_IS_CLASSED (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_CLASSED));
g_assert_false (G_TYPE_IS_DEEP_DERIVABLE (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DEEP_DERIVABLE));
g_assert_true (G_TYPE_IS_DERIVABLE (TEST_TYPE_INTERFACE));
g_assert_true (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DERIVABLE));
g_assert_false (G_TYPE_IS_FINAL (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_FINAL));
g_assert_false (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_INSTANTIATABLE));
}
#define TEST_TYPE_FINAL (test_final_get_type())
G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
struct _TestFinal
{
GObject parent_instance;
};
struct _TestFinalClass
{
GObjectClass parent_class;
};
G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT)
static void
test_final_class_init (TestFinalClass *klass)
{
}
static void
test_final_init (TestFinal *self)
{
}
#define TEST_TYPE_FINAL2 (test_final2_get_type())
G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal)
struct _TestFinal2
{
TestFinal parent_instance;
};
struct _TestFinal2Class
{
TestFinalClass parent_class;
};
G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL)
static void
test_final2_class_init (TestFinal2Class *klass)
{
}
static void
test_final2_init (TestFinal2 *self)
{
}
/* test_type_flags_final: Check that trying to derive from a final class
* will result in a warning from the type system
*/
static void
test_type_flags_final (void)
{
GType final2_type;
g_assert_true (G_TYPE_IS_FINAL (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_FINAL));
g_assert_true (G_TYPE_IS_CLASSED (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_CLASSED));
g_assert_true (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_INSTANTIATABLE));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL,
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE));
g_assert_false (g_type_test_flags (TEST_TYPE_FINAL,
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_INSTANTIATABLE));
/* This is the message we print out when registering the type */
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
"*cannot derive*");
/* This is the message when we fail to return from the GOnce init
* block within the test_final2_get_type() function
*/
g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
"*g_once_init_leave_pointer: assertion*");
final2_type = TEST_TYPE_FINAL2;
g_assert_true (final2_type == G_TYPE_INVALID);
g_test_assert_expected_messages ();
}
#define TEST_TYPE_DEPRECATED (test_deprecated_get_type())
G_DECLARE_FINAL_TYPE (TestDeprecated, test_deprecated, TEST, DEPRECATED, GObject)
struct _TestDeprecated
{
GObject parent_instance;
};
struct _TestDeprecatedClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE_EXTENDED (TestDeprecated, test_deprecated, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED, {})
static void
test_deprecated_class_init (TestDeprecatedClass *klass)
{
}
static void
test_deprecated_init (TestDeprecated *self)
{
}
static void
test_type_flags_final_instance_check (void)
{
TestFinal *final;
final = g_object_new (TEST_TYPE_FINAL, NULL);
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
TEST_TYPE_FINAL));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
TEST_TYPE_DEPRECATED));
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
G_TYPE_OBJECT));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
G_TYPE_INVALID));
g_clear_object (&final);
}
static void
test_type_flags_deprecated (void)
{
GType deprecated_type;
GObject *deprecated_object = NULL;
g_test_summary ("Test that trying to instantiate a deprecated type results in a warning.");
/* This is the message we print out when registering the type */
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING,
"*The type TestDeprecated is deprecated and shouldnt be used any more*");
/* The type itself should not be considered invalid. */
deprecated_type = TEST_TYPE_DEPRECATED;
g_assert_false (deprecated_type == G_TYPE_INVALID);
g_assert_true (G_TYPE_IS_DEPRECATED (deprecated_type));
g_assert_true (G_TYPE_IS_FINAL (deprecated_type));
g_assert_true (g_type_test_flags (deprecated_type, G_TYPE_FLAG_FINAL));
g_assert_true (g_type_test_flags (deprecated_type,
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_INSTANTIATABLE));
g_assert_false (g_type_test_flags (deprecated_type,
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_ABSTRACT |
G_TYPE_FLAG_INSTANTIATABLE));
/* Instantiating it should work, but emit a warning. */
deprecated_object = g_object_new (deprecated_type, NULL);
g_assert_nonnull (deprecated_object);
g_test_assert_expected_messages ();
g_object_unref (deprecated_object);
/* Instantiating it again should not emit a second warning. */
deprecated_object = g_object_new (deprecated_type, NULL);
g_assert_nonnull (deprecated_object);
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
TEST_TYPE_DEPRECATED));
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
G_TYPE_OBJECT));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
TEST_TYPE_FINAL));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
G_TYPE_INVALID));
g_test_assert_expected_messages ();
g_object_unref (deprecated_object);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
g_test_add_func ("/type/flags/interface", test_type_flags_interface);
g_test_add_func ("/type/flags/final", test_type_flags_final);
g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);
return g_test_run ();
}