Build fails with -Werror=strict-aliasing
When building with -Werror=strict-aliasing
, the build fails:
ninja: Entering directory `build'
[1/44] ccache cc -Isrc/libadwaita-1.so.0.p -Isrc -I../src -I. -I.. -Isrc/stylesheet -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/fribidi -I/usr/lib64/libffi/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/gtk-4.0 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/graphene-1.0 -I/usr/lib64/graphene-1.0/include -I/usr/include/gio-unix-2.0 -fvisibility=hidden -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu11 -O2 -g -DHAVE_CONFIG_H -DADWAITA_COMPILATION -Wcast-align -Wdate-time -Werror=format-security -Werror=format=2 -Wendif-labels -Werror=incompatible-pointer-types -Werror=missing-declarations -Werror=overflow -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=implicit-fallthrough=3 -Wformat-nonliteral -Wformat-security -Winit-self -Wmaybe-uninitialized -Wmissing-field-initializers -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wno-missing-field-initializers -Wno-sign-compare -Wno-strict-aliasing -Wno-unused-parameter -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wtype-limits -Wundef -Wunused-function -fstack-protector-strong -Werror=strict-aliasing -fPIC -mfpmath=sse -msse -msse2 -pthread '-DG_LOG_DOMAIN="Adwaita"' -MD -MQ src/libadwaita-1.so.0.p/adw-tab-view.c.o -MF src/libadwaita-1.so.0.p/adw-tab-view.c.o.d -o src/libadwaita-1.so.0.p/adw-tab-view.c.o -c ../src/adw-tab-view.c
FAILED: src/libadwaita-1.so.0.p/adw-tab-view.c.o
ccache cc -Isrc/libadwaita-1.so.0.p -Isrc -I../src -I. -I.. -Isrc/stylesheet -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/fribidi -I/usr/lib64/libffi/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/gtk-4.0 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/graphene-1.0 -I/usr/lib64/graphene-1.0/include -I/usr/include/gio-unix-2.0 -fvisibility=hidden -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu11 -O2 -g -DHAVE_CONFIG_H -DADWAITA_COMPILATION -Wcast-align -Wdate-time -Werror=format-security -Werror=format=2 -Wendif-labels -Werror=incompatible-pointer-types -Werror=missing-declarations -Werror=overflow -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=implicit-fallthrough=3 -Wformat-nonliteral -Wformat-security -Winit-self -Wmaybe-uninitialized -Wmissing-field-initializers -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wno-missing-field-initializers -Wno-sign-compare -Wno-strict-aliasing -Wno-unused-parameter -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wtype-limits -Wundef -Wunused-function -fstack-protector-strong -Werror=strict-aliasing -fPIC -mfpmath=sse -msse -msse2 -pthread '-DG_LOG_DOMAIN="Adwaita"' -MD -MQ src/libadwaita-1.so.0.p/adw-tab-view.c.o -MF src/libadwaita-1.so.0.p/adw-tab-view.c.o.d -o src/libadwaita-1.so.0.p/adw-tab-view.c.o -c ../src/adw-tab-view.c
In file included from /usr/lib64/glib-2.0/include/glibconfig.h:9,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from src/adw-version.h:13,
from ../src/adw-tab-view.h:15,
from ../src/adw-tab-view-private.h:15,
from ../src/adw-tab-view.c:11:
../src/adw-tab-view.c: In function ‘adw_tab_view_dispose’:
../src/adw-tab-view.c:1269:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
1269 | g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
/usr/include/glib-2.0/glib/gmacros.h:820:47: note: in definition of macro ‘G_STATIC_ASSERT’
820 | #define G_STATIC_ASSERT(expr) _Static_assert (expr, "Expression evaluates to false")
| ^~~~
../src/adw-tab-view.c:1269:3: note: in expansion of macro ‘g_clear_pointer’
1269 | g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
| ^~~~~~~~~~~~~~~
In file included from /usr/include/glib-2.0/glib/gatomic.h:28,
from /usr/include/glib-2.0/glib/gthread.h:32,
from /usr/include/glib-2.0/glib/gasyncqueue.h:32,
from /usr/include/glib-2.0/glib.h:32,
from src/adw-version.h:13,
from ../src/adw-tab-view.h:15,
from ../src/adw-tab-view-private.h:15,
from ../src/adw-tab-view.c:11:
../src/adw-tab-view.c:1269:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
1269 | g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
/usr/include/glib-2.0/glib/glib-typeof.h:36:36: note: in definition of macro ‘glib_typeof’
36 | #define glib_typeof(t) __typeof__ (t)
| ^
../src/adw-tab-view.c:1269:3: note: in expansion of macro ‘g_clear_pointer’
1269 | g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
| ^~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
ninja: build stopped: subcommand failed.
This is due to two casts, one in src/adw-tab-box.c:
g_clear_pointer ((GtkWidget **) &self->context_menu, gtk_widget_unparent);
and another in src/adw-tab-view.c:
g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
In both cases an object (GtkStack
or GtkPopover
) is being cast to a GtkWidget **
in order to be passed to g_clear_pointer
. This breaks C's aliasing rules, which I guess is where GTK_WIDGET
and G_TYPE_CHECK_INSTANCE_CAST
are supposed to help out?
I don't see a similar macro for handling double-pointers, but open-coding g_clear_pointer
and using GTK_WIDGET
I think solves the issue:
diff --git a/src/adw-tab-box.c b/src/adw-tab-box.c
index 4dfc5b0d..25989605 100644
--- a/src/adw-tab-box.c
+++ b/src/adw-tab-box.c
@@ -3407,7 +3407,8 @@ adw_tab_box_unrealize (GtkWidget *widget)
{
AdwTabBox *self = ADW_TAB_BOX (widget);
- g_clear_pointer ((GtkWidget **) &self->context_menu, gtk_widget_unparent);
+ gtk_widget_unparent (GTK_WIDGET (self->context_menu));
+ self->context_menu = NULL;
GTK_WIDGET_CLASS (adw_tab_box_parent_class)->unrealize (widget);
diff --git a/src/adw-tab-view.c b/src/adw-tab-view.c
index e54005b3..2e138713 100644
--- a/src/adw-tab-view.c
+++ b/src/adw-tab-view.c
@@ -1266,7 +1266,8 @@ adw_tab_view_dispose (GObject *object)
g_clear_object (&self->children);
- g_clear_pointer ((GtkWidget **) &self->stack, gtk_widget_unparent);
+ gtk_widget_unparent (GTK_WIDGET (self->stack));
+ self->stack = NULL;
G_OBJECT_CLASS (adw_tab_view_parent_class)->dispose (object);
}
I don't know if there's a better way to resolve this. If the inline diff is acceptable, I'm happy to make a merge request.