When calling `g_set_object()` for a type derived from `GObject`, GCC 9.2
was giving the following strict aliasing warning:
```
../../source/malcontent/libmalcontent-ui/user-controls.c:1001:21: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
1001 | if (g_set_object (&self->user, user))
/opt/gnome/install/include/glib-2.0/gobject/gobject.h:744:33: note: in definition of macro ‘g_set_object’
744 | (g_set_object) ((GObject **) (object_ptr), (GObject *) (new_object)) \
| ^~~~~~~~~~
```
This was due to the `(GObject **)` cast.
Pass the pointer through a union to squash this warning. We already do
some size and type checks of the dereferenced type, which should catch
casual errors. The `g_object_ref()` and `g_object_unref()` calls which
subsequently happen inside the `g_set_object()` function also do some
dynamic type checks.
Add a test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
As with `g_variant_new()` (or any varargs function which takes integer
literals of differing widths), callers need to be careful to ensure
their integer literals have the right width.
Tweak the documentation for `g_object_new()`, `g_object_set()` and
`g_object_get()` to clarify this. The documentation for `g_object_get()`
shows that it is not subject to the same caveats, since it operates on
pointers.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #833
While we automatically define cleanup functions for the module, we don't
do it for the module class.
This will allow to manage the ownership of the class when reffing it
without having to cast it to GTypeClass.
The `G_TYPE_IS_INSTANTIATABLE()` check is redundant with a precondition
on the function.
The `g_type_class_peek()` check seems like a pointless restriction: it
should be possible to check for a signal from a class init function.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #650
Use the new g_type_interface_instantiable_prerequisite() to check
compatibility for transform functions.
In particular, this allows interfaces (in my case GDK_TYPE_PAINTABLE) to
be transformed to/from any GObject type (in my case G_TYPE_OBJECT) using
the transform function registered to tranform between any 2 objects
(g_value_object_transform_value() does a type check and uses NULL if the
types don't match).
And this in turn allows be to g_object_bind_property() a gobject-typed
generic property (GtkListItem::item) to a GtkImage::paintable.
Use the newly added g_type_interface_instantiable_prerequisite() to
allow closure return values being interfaces by looking up the
instantiable type for the interface and usings its GValue accessors.
There is (at most) a single GType that is instantiable and a
prerequisite for an interface. This function returns that type.
This type is necessary in particular when dealing with GValues because a
GValue contains an instance of a type.
The format has never previously been specified. It can be anything, but
for sanity’s sake disallow empty strings.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This will allow subsequent testing of property name canonicalisation.
This test introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Rather than adding a canonicalised and non-canonicalised version of the
signal to `g_signal_key_bsa`, just add the canonicalised version. Signal
lookups always use the canonicalised key (since the previous commit).
This saves space in `g_signal_key_bsa`, which should speed up lookups;
and it saves significant space in the global `GQuark` table (a 9.6%
reduction in entries in that table, by a rough test using
gnome-software).
We have to be a little more relaxed on the signal name validation than
we are for property name validation, as GTK installs a
`-gtk-private-changed` signal which violates the signal naming rules.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Previously, we’d look up the signal name as passed to (for example)
`g_signal_lookup()`, and rely on the fact that signals are inserted
twice into `g_signal_key_bsa`; once in canonical form and once not.
In preparation for only inserting signals into `g_signal_key_bsa` once,
we now try looking up a signal with the given signal name and, if that
fails, try canonicalising the name and trying again.
This is a performance hit on lookups for non-canonical names, but
shouldn’t affect the performance of lookups for canonical names. If
people want performance, they should use canonical names.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
This eliminates a call from every call site of signal_id_lookup(). It
introduces no functional changes, but allows subsequent refactoring.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Since signal names are the same as property names, reference between the
two. Improve the formatting, and make it clearer that `_` is
discouraged.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Interned strings are never freed, so we don’t need to take a copy of
them when returning them in a #GValue. This is a minor memory allocation
improvement, with no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Rather than interning a property name string which isn’t canonicalised,
canonicalise it first, and enforce stricter validation on inputs.
The previous code was not incorrect (since the property machinery would
have canonicalised the property names itself, internally), but would
have resulted in non-canonical property names getting into the GQuark
table unnecessarily. With the new code, the interned property names from
property installation time should be consistently reused.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Inline with the stricter version of the property naming rules from the
documentation, tighten up the validation of property names at
installation time.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The documentation says that parameter names must be alphanumeric (plus
`-` or `_`) and that canonicalisation turns `_` into `-`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
There’s no need to have the property naming documentation in two places,
with one version of it being stricter than the other. Rationalise it to
one place, link to that consistently, and settle on the stricter
version.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
We cannot just call
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, &dflt_value);
without initializing the GValue first. It would call
param_string_set_default(), which would set the pointer value
to a cloned string (which later never gets released, because
the GValue is not known to hold a string).
Fixes: 6ad799ac67
Since we have the type of the GValue we're going to initialize, we can
allow passing an empty (but valid) GValue when retrieving the default
value of a GParamSpec.
This will eliminate additional checks and an unnecessary reset.
If we're cross-compiling, the installed-tests are useful even if we
can't run them on the build machine: we can copy them to the host
machine (possibly via a distro package like Debian's libglib2.0-tests)
and run them there.
While I'm changing the build-tests condition anyway, deduplicate it.
Based on a patch by Helmut Grohne.
Bug-Debian: https://bugs.debian.org/941509
Signed-off-by: Simon McVittie <smcv@collabora.com>
I don’t think these could be hit in practice due to the guarantees of
the type system, but the static analyser doesn’t know that — so make the
assertions clearer to shut it up.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
The static analyser can’t yet work out how `g_autofree` works, so
disable those tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
The macros for the probes confuse the static analyser, and are often
called with arguments which the analyser things shouldn’t be used any
more (for example, the address of a block of memory which has just been
freed).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
The previous documentation said this:
g_type_add_interface_static:
"Adds the static interface_type to instantiable_type"
g_type_add_interface_dynamic:
"Adds the dynamic interface_type to instantiable_type"
The above suggests that if one is adding a static interface to a dynamic
object, one should use g_type_add_interface_static because the interface
is static, but the code and usage (with the newly added
G_IMPLEMENTS_INTERFACE_DYNAMIC) imply that this is wrong, and that
what matters is whether the *instanciable_type* is dynamic or not.
Hence this patch moves the "static" and "dynamic" words close to
"instantiable_type".
Closes issue #259
This uses a 32bit hole in the GObject structure on 64bit arches
as a flag field which can be optionally used for some preformance hints.
Currently there is a flag that gets set any time you connect to a signal
on a GObject which is used as early bailout for signal emissions, and using
the flags field instead of a user-data for checking if a GObject is
under construction.
The Python runtime is not amenable to Valgrind, and leak checking is a
lot less relevant in Python compared to C.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #487
These macros wrap functions which were only introduced in certain
versions of GLib. The functions are correctly marked as introduced in
those versions, but the macros aren’t, which can result in not getting
appropriate deprecation warnings if you’re using those APIs when you
have said you’re targeting older GLib versions using
`GLIB_VERSION_MAX_ALLOWED`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #1860
"Uninitialized value" is partially correct, since it has not been
initialized with a type, but it's more precise to say
"zero-initialized value". It is still a programming error to pass a
pointer to uninitialized memory with arbitrary contents as the value.
Signed-off-by: Simon McVittie <smcv@collabora.com>
We're using the `install` argument for configure_file() all over the
place.
The support for an `install` argument for configure_file() was added in
Meson 0.50, but we haven't bumped the minimum version of Meson we
require, yet; which means we're getting compatibility warnings when
using recent versions of Meson, and undefined behaviour when using older
versions.
The configure_file() object defaults to `install: false`, unless an
install directory is used. This means that all instances of an `install`
argument with an explicit `true` or `false` value can be removed,
whereas all instances of `install` with a value determined from a
configuration option must be turned into an explicit conditional.
Connect the dots between G_ADD_PRIVATE and the various G_DEFINE_* macros
that use it, as well as expanding the code example for
G_DEFINE_TYPE_EXTENDED with a private instance data declaration.
Closes: #943
The two test scripts actually assumed some *NIX paradigms, so we need
to adapt them so that they can work on Windows as well, the changes are
namely:
-Call the glib-mkenums and glib-genmarshal Python scripts with the
Python interpreter, not just relying on shebang lines, on Windows.
This is because the native Windows console (cmd.exe) does not support
shebang lines, for subprocess.run().
-Use NamedTemporaryFile with delete=False, otherwise Windows cannot find
the temp files we need when running the tests.
-Use universal_newlines=True for subprocess.run() so that we do not need
to worry out line ending differences on different systems.
-Make sure we are not in the temp directories we create, where the tests
are being run, upon cleanup. Windows does not like deleting
directories that we are currently in.
On Windows and possibly other platforms the '%p' printf modifier does
not prefix printed values with '0x', so do not expect the warning
message to contain the '0x' prefix for the handler pointer value.
When building a valist marshaller, we can avoid reffing a GParamSpec
if the argument is known to always be static. The marshaller we ship in
`gmarshal.c` got this right, but marshallers generated by
glib-genmarshal were missing the optimisation. Fix that, and add a unit
test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1792
Using the generic marshaller has drawbacks beyond performance. One such
drawback is that it breaks the stack unwinding from the Linux kernel due
to having unsufficient data to walk past ffi_call_unixt64. That means that
performance profiling by application developers looks grouped among
seemingly unrelated code paths.
Related to GNOME/Initiatives#10
If we specify a c_marshaller, g_signal_newv() will never assign an
va_marshaller automatically. So either use NULL (for simple cases), or
specify both to avoid the generic performance penalty.
When building a valist marshaller, we can avoid a string copy if the
argument is known to always be static. The marshaller we ship in
`gmarshal.c` got this right, but marshallers generated by
glib-genmarshal were missing the optimisation. Fix that, and add a unit
test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1792
The old (Perl) implementation of glib-genmarshal used
g_variant_ref_sink() to correctly handle floating inputs; the Python
version should do the same.
Includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1793
This is a basic test suite for the `glib-genmarshal` utility, lifted
mostly directly from the tests for `glib-mkenums`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This makes the Meson build code for it a little more generic, and adds
support for installed tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
While this was useful for local testing while developing the test, it’s
not widely applicable. Look the binary up in the current `${PATH}` if
it’s not specified using `G_TEST_BUILDDIR`.
This is needed to get the `mkenums.py` test working as an
installed-test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
We already have the GType with which the GValue should be initialized,
so requiring an initialized GValue is not really necessary, and it
actually complicates code that wraps GObject, by requiring the retrieval
of the GParamSpec in order to get the property type. Additionally, it
introduces a mostly unnecessary g_value_reset().
We already changed g_object_getv() to allow passing uninitialized
GValues, but this fell through the cracks.
Closes: #737
These have all been documented as deprecated for a long time, but we’ve
never had a way to programmatically mark them as deprecated. Do that
now.
This is based on the list of deprecations from the reverted commit
80fcb1bc2.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #638
Use the new `GLIB_DEPRECATED_{TYPE,ENUMERATOR}*` macros to annotate types
and enumerators as deprecated, rather than using `G_DISABLE_DEPRECATED`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It allows to disconnect a signal handler from GObject instance and at the same
time to nullify the signal handler.
Provided also a macro for handler type conversion.