gobject/gobject.c: In function ‘g_object_new_internal’:
gobject/gobject.c:1962:25: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1962 | for (j = 0; j < n_params; j++)
| ^
gobject/gobject.c:1989:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1989 | for (i = 0; i < n_params; i++)
| ^
gobject/gobject.c: In function ‘g_object_new_with_custom_constructor’:
gobject/gobject.c:1836:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1836 | for (j = 0; j < n_params; j++)
| ^
gobject/gobject.c:1914:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1914 | for (i = 0; i < n_params; i++)
| ^
gobject/gobject.c: In function ‘g_object_class_install_properties’:
gobject/gobject.c:766:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
766 | for (i = 1; i < n_pspecs; i++)
| ^
gobject/gtype.c: In function ‘g_type_interface_add_prerequisite’:
gobject/gtype.c:1607:21: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
1607 | for (i = 0; i < prerequisite_node->n_supers + 1; i++)
| ^
The problem occurs because we keep a pointer inside the allocated block,
instead of a pointer to the start of the block. This memory exists for
the lifetime of the application, so let's silence it.
This is probably abuse of VALGRIND_MALLOCLIKE_BLOCK(), which is really
intended for use in memory allocators, but gtype.c already uses it in
two other places, and it's a practical solution. I wrote another larger
fix for this issue that involves keeping an array of extra pointers when
running under valgrind. This is simpler.
Fix suggested by Philip Withnall
```
==180238== 16 bytes in 1 blocks are possibly lost in loss record 3,078 of 16,075
==180238== at 0x483BB1A: calloc (vg_replace_malloc.c:762)
==180238== by 0x5489495: g_malloc0 (gmem.c:132)
==180238== by 0x5489754: g_malloc0_n (gmem.c:364)
==180238== by 0x53FDBEE: type_set_qdata_W (gtype.c:3722)
==180238== by 0x53FDEE8: type_add_flags_W (gtype.c:3787)
==180238== by 0x53FC348: g_type_register_fundamental (gtype.c:2662)
==180238== by 0x53D969B: _g_enum_types_init (genums.c:124)
==180238== by 0x53FF058: gobject_init (gtype.c:4432)
==180238== by 0x53FF082: gobject_init_ctor (gtype.c:4493)
==180238== by 0x4010F29: call_init.part.0 (dl-init.c:72)
==180238== by 0x4011030: call_init (dl-init.c:30)
==180238== by 0x4011030: _dl_init (dl-init.c:119)
==180238== by 0x4002149: ??? (in /usr/lib64/ld-2.30.so)
```
Fixes#2076
The problem occurs because we keep a pointer inside the allocated block,
instead of a pointer to the start of the block:
```
==180238== 16 bytes in 1 blocks are possibly lost in loss record 3,086 of 16,075
==180238== at 0x483980B: malloc (vg_replace_malloc.c:309)
==180238== by 0x548942C: g_malloc (gmem.c:102)
==180238== by 0x54A4748: g_slice_alloc (gslice.c:1025)
==180238== by 0x53D0AAF: freelist_alloc (gatomicarray.c:77)
==180238== by 0x53D0B85: _g_atomic_array_copy (gatomicarray.c:133)
==180238== by 0x53F8E6D: iface_node_set_offset_L (gtype.c:1347)
==180238== by 0x53F91F1: type_node_add_iface_entry_W (gtype.c:1444)
==180238== by 0x53F93DF: type_add_interface_Wm (gtype.c:1477)
==180238== by 0x53FC946: g_type_add_interface_static (gtype.c:2852)
==180238== by 0x4A3D53A: gtk_menu_shell_accessible_get_type_once (gtkmenushellaccessible.c:26)
==180238== by 0x4A3D495: gtk_menu_shell_accessible_get_type (gtkmenushellaccessible.c:26)
==180238== by 0x4C8AC44: gtk_menu_shell_class_init (gtkmenushell.c:424)
```
Note we cannot use VALGRIND_FREELIKE_BLOCK() in freelist_free() because we
have not actually freed the FreeListNode and need to dereference it in
freelist_alloc() to decide whether to reuse the block. That would result
in a use-after-free warning before we would get a chance to call
VALGRIND_MALLOCLIKE_BLOCK() in the reuse path.
Also note that this free list only ever grows: it never shrinks for the
lifetime of the application, so nothing here will ever be truely freed,
although unused elements are eligible for reuse.
Fix suggested by Philip Withnall
Related: #2076
gobject/gtype.c: In function ‘type_node_add_iface_entry_W’:
gobject/gtype.c:1379:21: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
1379 | for (i = 0; i < num_entries; i++)
| ^
gobject/gtype.c: In function ‘lookup_iface_entry_I’:
gobject/gtype.c:599:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
599 | if (index < IFACE_ENTRIES_N_ENTRIES (entries))
| ^
gobject/gatomicarray.h:51:8: note: in definition of macro ‘G_ATOMIC_ARRAY_DO_TRANSACTION’
51 | {_C_;} \
| ^~~
Half of the references to `init_state` in `gtype.c` already correctly
accessed it atomically, but a couple didn’t. Drop the `volatile`
qualifier from its declaration, as that’s not necessary for atomic
access.
Note that this is the `init_state` in `TypeData`, *not* the `init_state`
in `IFaceEntry`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
These variables were already (correctly) accessed atomically. The
`volatile` qualifier doesn’t help with that.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
This is an API break, but no third party code should be touching
`GObject.ref_count`, let alone in a way which would be changed by the
removal of the `volatile` qualifier.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
This is an API break, but it should not affect third party code since
that code should not be interacting with the `data` member in a way that
invokes its `volatile` qualifier (such as copying to an intermediate
variable).
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
These variables were already (correctly) accessed atomically. The
`volatile` qualifier doesn’t help with that.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
http://isvolatileusefulwiththreads.in/c/
It’s possible that the variables here are only marked as volatile
because they’re arguments to `g_once_*()`. Those arguments will be
modified in a subsequent commit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
The previous code consumed a larger additional amount of stack space.
That is because it would allocate the temporary buffer for GValues on
the stack with "g_newa (GValue, 1)" and thus the required stack
space grew with the number of arguments. Granted, this is already
a variadic C function, so the caller already placed that many elements
on the stack. For example, on the stack there are the property names
and the pointers to the arguments, which should amount to roughly
O(n_args * 16) (on 64 bit, with pointers being 8 bytes large).
That is not bad, because it means in the previous version the stack space
would grow linear with the already used stack space. However, a GValue is
an additional 24 bytes (on 64 bit), which probably more than doubles the
required stack space. Let's avoid that, by allocating the temporary list
on the heap after a certain threshold. This probably more than doubles the
number of possible arguments before the stack overflows.
Also, previously the heap allocated "params" array only grew one element
per iteration. Of course, it is likely that libc anyway reallocates
the buffers by growing the space exponentially. So realloc(ptr, 1)
probably does not O() scale worse than doubling the buffer sizes ourselves.
However, it seems clearer to keep track of the allocated sizes ourself, and
only call realloc() when we determine that we are out of space.
Especially because we need to update the value pointers on reallocation.
Note that we now require a heap allocation both for the "params" and the
"values" list. Theoretically that could be combined by using one buffer
for both. But that would make the code more complicated.
Now we pre-allocate buffers for 16 elements on the stack. That
is (16 * (16 + 24) bytes (or 640 bytes) on the stack. I think that
is still acceptable.
Two out of three callers pass the count argument from a variable
of type guint. And the third is currently an always positive gint.
We should use the correct integer type that matches the type as it
used otherwise.
This commit is the unmodified results of running
```
black $(git ls-files '*.py')
```
with black version 19.10b0. See #2046.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Add a test for a signal returning interface types, using
the generic marshaller. This will hopefully exercise newly
added code in value_from_ffi_type().
This tests the new functionality that
g_type_interface_instantiable_prerequisite
was added for.
Before the changes, this fails with
GObject-WARNING **: Unable to convert a value of type \
GObject to a value of type Foo
We do the same test with g_object_bind_property_with_closures
as well, to exercise g_cclosure_marshal_generic.
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 transform 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.
Tests for the new functionality are included.
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 using its GValue accessors.
This function returns the most specific instantiatable type
that is a prerequisite for a given interface.
This type is necessary in particular when dealing with GValues
because a GValue contains an instance of a type.
This commit includes tests for the new API.
Rather than using a mixture of ‘instantiable’ and ‘instantiatable’
everywhere, standardise on the term which is already in the public API.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
g_has_typeof macro is wrongly in the public g_ namespace, internaly
symbols are usually in the glib_ namespace. This will also allow to
define glib_typeof differently on non-GNUC compilers (e.g. c++11
decltype).
commit 916297be79 added a hash table
to provide constant time lookups of signal handlers.
Unfortunately, that commit neglected to remove handlers from
g_signal_connect_object calls from the hash table that are
disconnected implicitly when the associated object goes away.
This commit addresses that bug by changing the closure invalidate
handler associated with the signal connection to properly remove the
handler from the hash table.
It may be defined by the environment (we document that as being allowed)
— if so, individual files should not try to redefine it, as that causes
a preprocessor warning.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Add a set of new URI parsing and generating functions, including a new
parsed-URI type GUri. Move all the code from gurifuncs.c into guri.c,
reimplementing some of those functions (and
g_string_append_uri_encoded()) in terms of the new code.
Fixes:
https://gitlab.gnome.org/GNOME/glib/issues/110
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The G_VALUE_NOCOPY_CONTENTS for strings can only be used when collecting them
and not when copying them.
Instead only avoid copies for strings that are interned.
Fixes#2141
This was mostly machine generated with the following command:
```
codespell \
--builtin clear,rare,usage \
--skip './po/*' --skip './.git/*' --skip './NEWS*' \
--write-changes .
```
using the latest git version of `codespell` as per [these
instructions](https://github.com/codespell-project/codespell#user-content-updating).
Then I manually checked each change using `git add -p`, made a few
manual fixups and dropped a load of incorrect changes.
There are still some outdated or loaded terms used in GLib, mostly to do
with git branch terminology. They will need to be changed later as part
of a wider migration of git terminology.
If I’ve missed anything, please file an issue!
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Some editors automatically remove trailing blank lines, or
automatically add a trailing newline to avoid having a trailing
non-blank line that is not terminated by a newline. To avoid unrelated
whitespace changes when users of such editors contribute to GLib,
let's pre-emptively normalize all files.
Unlike more intrusive whitespace normalization like removing trailing
whitespace from each line, this seems unlikely to cause significant
issues with cherry-picking changes to stable branches.
Implemented by:
find . -name '*.[ch]' -print0 | \
xargs -0 perl -0777 -p -i -e 's/\n+\z//g; s/\z/\n/g'
Signed-off-by: Simon McVittie <smcv@collabora.com>
The various `g_strdup_printf()` returns values in the implementations of GValue
lcopy_func are runtime checks which could be disabled if one wants and therefore
should be handled as such with g_return_val_if_fail()
The property strings are interned already, so this potentially allows for faster
comparisons. The property strings were already not copied, as they were tagged
as static.
This adds support to be able to explicitely stored interned strings into
G_TYPE_STRING GValue.
This is useful for cases where the user:
* *knows* the string to be stored in the GValue is canonical
* Wants to know whther the string stored is canonical
This allows:
* zero-cost GValue copy (the content is guaranteed to be unique and exist
throughout the process life)
* zero-cost string equality checks (if both string GValue are interned, you just
need to check the pointers for equality or not, instead of doing a strcmp).
Fixes#2109