https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110611
Bug ID: 110611 Summary: X86 is not honouring POINTERS_EXTEND_UNSIGNED in m32 code. Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: iains at gcc dot gnu.org Target Milestone: --- I've made this target but not sure exactly where it lies - the gimplifier output looks suspect already - so maybe it's gimplifer/frontend. this code is distilled from a version of GDB (7.12) where 'bar' is a system call that breaks with a sign-extended pointer... the x86 backend sets: gcc/config/i386/i386.h:#define POINTERS_EXTEND_UNSIGNED 1 which ought, according to gccint mean that pointers get sign-extended... t.c ==== typedef unsigned long long uint64_t; typedef uint64_t another_t; typedef unsigned char byte; extern void bar (another_t y, another_t z); void foo (byte *p) { another_t x = (another_t)p; bar ((another_t) p, x); } === build : $(compiler) -m32 t.c -S -fdump-tree-gimple -Wall -Wextra * If built by the GCC compiler, we get warnings like; warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 9 | another_t x = (another_t)p; * if built by G++ we get no warnings However, in both cases, the generated assembler sign-extends *p => x and the first arg to bar. gimple: void foo (byte * p) { another_t x; p.0_1 = (int) p; x = (another_t) p.0_1; p.1_2 = (int) p; _3 = (long long unsigned int) p.1_2; bar (_3, x); } maybe the combination of 'perhaps wrong' user code, plus the maze of typedefs is confusing something.