On Thu, May 28, 2026 at 5:40 AM Iain Sandoe <[email protected]> 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?
> >>
> >> Jason
> >>
> >
> > This:
> >
> > 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;
> > +
> >   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.
>

Try this.


-- 
H.J.
From 5590d62c20c1bfed2926920cba34b0149c5fd5eb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Fri, 8 May 2026 12:20:02 +0800
Subject: [PATCH] c/c++: Return intptr type first in c_common_type_for_mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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.  Change c_common_type_for_mode to return
intptr type first to first the type mismatch.

gcc/c-family/

	PR c/125226
	* c-common.cc (c_common_type_for_mode): Return intptr type first.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/c-family/c-common.cc | 3 +++
 1 file changed, 3 insertions(+)

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;
+
   if (mode == TYPE_MODE (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
 
-- 
2.54.0

Reply via email to