diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-05-07 23:35:17 +0100 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-05-08 17:02:54 +0100 |
commit | ae4c44466742d74a4a3f951757a23c88f9699464 (patch) | |
tree | 47b9b860d49c432b46385fd68b6232c254a27e92 /tests | |
parent | 9221b85d5f41a666b2a3551b373330d9eca14a63 (diff) |
clang-plugin: Add a g_signal_connect() checker
This validates that:
• The named signal exists on the given GObject subclass.
• The type of the callback function matches that declared for the
signal.
Unit tests are included.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/gsignal-connect.c | 174 | ||||
-rw-r--r-- | tests/gsignal.head.c | 82 | ||||
-rw-r--r-- | tests/gsignal.tail.c | 4 |
4 files changed, 263 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 26d1c02..3fc9e91 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,6 +8,7 @@ C_LOG_COMPILER = $(top_srcdir)/tests/wrapper-compiler-errors c_tests = \ assertion-extraction.c \ assertion-extraction-return.c \ + gsignal-connect.c \ gvariant-builder.c \ gvariant-get.c \ gvariant-get-child.c \ @@ -24,6 +25,8 @@ templates = \ assertion-return.tail.c \ generic.head.c \ generic.tail.c \ + gsignal.head.c \ + gsignal.tail.c \ gvariant.head.c \ gvariant.tail.c \ $(NULL) diff --git a/tests/gsignal-connect.c b/tests/gsignal-connect.c new file mode 100644 index 0000000..7f529bf --- /dev/null +++ b/tests/gsignal-connect.c @@ -0,0 +1,174 @@ +/* Template: gsignal */ + +/* + * No error + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", (GCallback) object_notify_cb, + NULL); +} + +/* + * No error + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + + // Detailed signal + // FIXME: Check the detail is a valid property name too? + g_signal_connect (some_object, "notify::something", + (GCallback) object_notify_cb, NULL); +} + +/* + * No error + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_proto_cb, + NULL); +} + +/* + * Could not check type of handler for signal ‘GObject::notify’. Callback function declaration does not contain parameter types. + * (GCallback) object_notify_no_proto_cb, + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_no_proto_cb, + NULL); +} + +/* + * Incorrect return type from signal handler for signal ‘GObject::notify’. Expected ‘void’ but saw ‘gboolean’. + * (GCallback) object_notify_invalid_return_cb, NULL); + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_return_cb, NULL); +} + +/* + * Incorrect type for argument 1 in signal handler for signal ‘GObject::notify’. Expected ‘GObject *’ but saw ‘GIOStream *’. + * (GCallback) object_notify_invalid_parameter_subclass_cb, + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_parameter_subclass_cb, + NULL); +} + +/* + * Incorrect type for argument 1 in signal handler for signal ‘GObject::notify’. Expected ‘GObject *’ but saw ‘const GObject *’. + * (GCallback) object_notify_invalid_parameter_const_cb, + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_parameter_const_cb, + NULL); +} + +/* + * Incorrect type for argument 2 in signal handler for signal ‘GObject::notify’. Expected ‘GParamSpec *’ but saw ‘void *’. + * (GCallback) object_notify_invalid_parameter_middle_cb, + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_parameter_middle_cb, + NULL); +} + +/* + * Incorrect type for argument 3 in signal handler for signal ‘GObject::notify’. Expected ‘void *’ but saw ‘guint’. + * (GCallback) object_notify_invalid_parameter_user_data_cb, + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_parameter_user_data_cb, + NULL); +} + +/* + * No error + */ +{ + // Non-void* pointer types for user_data are allowed. + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_invalid_parameter_user_data_ptr_cb, + NULL); +} + +/* + * Incorrect number of arguments in signal handler for signal ‘GObject::notify’. Expected 3 but saw 2. + * (GCallback) object_notify_missing_parameter_cb, NULL); + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_missing_parameter_cb, NULL); +} + +/* + * Incorrect number of arguments in signal handler for signal ‘GObject::notify’. Expected 3 but saw 4. + * (GCallback) object_notify_extra_parameter_cb, NULL); + * ^ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "notify", + (GCallback) object_notify_extra_parameter_cb, NULL); +} + +/* + * No signal named ‘invalid-signal’ in GObject class ‘Object’. + * g_signal_connect (some_object, "invalid-signal", + * ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * note: expanded from macro 'g_signal_connect' + * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + * ^ ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ + */ +{ + GObject *some_object = g_malloc (5); // only checking the type + g_signal_connect (some_object, "invalid-signal", + (GCallback) object_notify_cb, NULL); +} diff --git a/tests/gsignal.head.c b/tests/gsignal.head.c new file mode 100644 index 0000000..8b6e1ac --- /dev/null +++ b/tests/gsignal.head.c @@ -0,0 +1,82 @@ +#include <stdio.h> + +#include <glib.h> +#include <glib-object.h> +#include <gio/gio.h> + +static void +object_notify_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data) +{ + /* Something */ +} + +extern void +object_notify_proto_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data); + +extern void +object_notify_no_proto_cb (); + +static gboolean +object_notify_invalid_return_cb (GObject *gobject, GParamSpec *pspec, + gpointer user_data) +{ + /* Something */ + return FALSE; +} + +static void +object_notify_invalid_parameter_subclass_cb (GIOStream *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + /* Something */ +} + +static void +object_notify_invalid_parameter_const_cb (const GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + /* Something */ +} + +static void +object_notify_invalid_parameter_middle_cb (GObject *gobject, + void *pspec, + gpointer user_data) +{ + /* Something */ +} + +static void +object_notify_invalid_parameter_user_data_cb (GObject *gobject, + GParamSpec *pspec, + guint user_data) +{ + /* Something */ +} + +static void +object_notify_invalid_parameter_user_data_ptr_cb (GObject *gobject, + GParamSpec *pspec, + GObject *user_data) +{ + /* Something */ +} + +static void +object_notify_missing_parameter_cb (GObject *gobject, GParamSpec *pspec) +{ + /* Something */ +} + +static void +object_notify_extra_parameter_cb (GObject *gobject, GParamSpec *pspec, + gpointer user_data, gpointer user_data2) +{ + /* Something */ +} + +int +main (void) +{ diff --git a/tests/gsignal.tail.c b/tests/gsignal.tail.c new file mode 100644 index 0000000..aa0c781 --- /dev/null +++ b/tests/gsignal.tail.c @@ -0,0 +1,4 @@ + /* End of main(). */ + + return 0; +} |