On 5/27/26 5:39 PM, Iain Sandoe wrote:
On 27 May 2026, at 22:03, H.J. Lu <[email protected]> wrote:
On Thu, May 28, 2026 at 4:16 AM Jason Merrill <[email protected]> wrote:
On 5/8/26 6:05 AM, H.J. Lu wrote:
default_stack_protect_guard calls
lang_hooks.types.type_for_mode (ptr_mode, 1);
to get an integer type for __stack_chk_guard which is declared as a
global symbol of type uintptr_t. For 32-bit systems, uintptr_t may
be either unsigned int or unsigned long int. On 32-bit Darwin, we get
$ cat /tmp/x.c
__UINTPTR_TYPE__ __stack_chk_guard = 0x1000;
$ ./xgcc -B./ -S /tmp/x.c -m32
/tmp/x.c:1:18: error: conflicting types for ‘__stack_chk_guard’; have
‘long unsigned int’
1 | __UINTPTR_TYPE__ __stack_chk_guard = 0x1000;
| ^~~~~~~~~~~~~~~~~
cc1: note: previous declaration of ‘__stack_chk_guard’ with type ‘unsigned int’
$
since lang_hooks.types.type_for_mode returns unsigned int while Darwin's
uintptr_t is unsigned long int.
Add LANG_HOOKS_TYPE_FOR_MODE_KIND to specify signed or unsigned integer
type for pointer and update default_stack_protect_guard to call
lang_hooks.types.type_for_mode_kind
(ptr_mode, 1, KIND_IS_INTEGER_FOR_POINTER);
to get unsigned integer type for pointer.
Instead of adding this additional parameter; can we just adjust the
existing c_common_type_for_mode handling of pointer modes, i.e.
if (mode == TYPE_MODE (build_pointer_type (char_type_node))
|| mode == TYPE_MODE (build_pointer_type (integer_type_node)))
{
unsigned int precision
= GET_MODE_PRECISION (as_a <scalar_int_mode> (mode));
return (unsignedp
? make_unsigned_type (precision)
: make_signed_type (precision));
}
to return [u]intptr_type_node?
Ah, I was confused, thinking that there were different modes for
pointers, but it seems they generally use normal integer modes, so you
can't tell by the mode whether it came from an integer or pointer. So
thus your patch.
A plausible kludge to avoid another hook would be to look at the
UINTPTR_TYPE target macro directly like build_common_tree_nodes does for
SIZE_TYPE:
else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
size_type_node = long_unsigned_type_node;
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index ac9c681d4b8..992e279f332 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -2455,6 +2455,9 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
tree t;
int i;
+ if (mode == TYPE_MODE (intptr_type_node))
+ return unsignedp ? uintptr_type_node : intptr_type_node;
This seems likely to mess up other uses of this function, like
finish_underlying_type.
Jason
if (mode == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
works for
__UINTPTR_TYPE__ __stack_chk_guard = 0x1000;
on Darwin. But I don't know if it will cause other issues for Darwin.
I very much doubt that the issues are confined to Darwin (it just happens to be
one of the earlier-tested non-linux platforms), what’s needed is something
generic
that works by construction.
Do you have a composite complete proposed patch?; I can certainly test such
a patch on affected darwin versions - but comment above remains.
Iain
--
H.J.