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.

gcc/

PR c/125226
* langhooks-def.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add
LANG_HOOKS_TYPE_FOR_MODE_KIND.
* langhooks.h (type_kind): New enum.
(lang_hooks_for_types): Add type_for_mode_kind.
* targhooks.c (default_stack_protect_guard): Call
lang_hooks.types.type_for_mode_kind if not NULL.

gcc/c-family/

PR c/125226
* c-common.cc (c_common_type_for_mode): Renamed to ...
(c_common_type_for_mode_kind): This.  Add an argument for type
kind.  Return intptr_type_node/uintptr_type_node when asking
for integer type for pointers.
(c_common_type_for_mode): New.  Call c_common_type_for_mode_kind
with KIND_IS_UNKNOWN.
* c-common.h: Include "langhooks.h".
(c_common_type_for_mode_kind): New prototype.
* c-objc-common.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.

gcc/cp/

PR c/125226
* cp-objcp-common.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.


-- 
H.J.
From 2a93ac6f24d5eb95c369b7b6f2ce83f29af33ffb 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++: Get unsigned integer type for pointer
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.

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.

gcc/

	PR c/125226
	* langhooks-def.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.
	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add
	LANG_HOOKS_TYPE_FOR_MODE_KIND.
	* langhooks.h (type_kind): New enum.
	(lang_hooks_for_types): Add type_for_mode_kind.
	* targhooks.c (default_stack_protect_guard): Call
	lang_hooks.types.type_for_mode_kind if not NULL.

gcc/c-family/

	PR c/125226
	* c-common.cc (c_common_type_for_mode): Renamed to ...
	(c_common_type_for_mode_kind): This.  Add an argument for type
	kind.  Return intptr_type_node/uintptr_type_node when asking
	for integer type for pointers.
	(c_common_type_for_mode): New.  Call c_common_type_for_mode_kind
	with KIND_IS_UNKNOWN.
	* c-common.h: Include "langhooks.h".
	(c_common_type_for_mode_kind): New prototype.
	* c-objc-common.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.

gcc/cp/

	PR c/125226
	* cp-objcp-common.h (LANG_HOOKS_TYPE_FOR_MODE_KIND): New.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/c-family/c-common.cc | 38 +++++++++++++++++++++++++++++++++++---
 gcc/c-family/c-common.h  |  2 ++
 gcc/c/c-objc-common.h    |  2 ++
 gcc/cp/cp-objcp-common.h |  2 ++
 gcc/langhooks-def.h      |  2 ++
 gcc/langhooks.h          |  7 +++++++
 gcc/targhooks.cc         |  8 +++++++-
 7 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 2bf71e54045..a906bb3ac90 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -2445,16 +2445,42 @@ tree registered_builtin_types;
 
 /* Return a data type that has machine mode MODE.
    If the mode is an integer,
-   then UNSIGNEDP selects between signed and unsigned types.
+   then KIND selects integer type for pointers, UNSIGNEDP selects
+   between signed and unsigned types.
    If the mode is a fixed-point mode,
-   then UNSIGNEDP selects between saturating and nonsaturating types.  */
+   then UNSIGNEDP selects between saturating and nonsaturating types.
+   */
 
 tree
-c_common_type_for_mode (machine_mode mode, int unsignedp)
+c_common_type_for_mode_kind (machine_mode mode, int unsignedp,
+			     type_kind kind)
 {
   tree t;
   int i;
 
+  /* NB: default_stack_protect_guard calls
+
+	lang_hooks.types.type_for_mode (ptr_mode, 1);
+
+    to get an integer type for __stack_chk_guard when it 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.  To avoid conflicting
+    types for __stack_chk_guard when uintptr_t is 32-bit unsigned long
+    int, return intptr_t/uintptr_t when asking for a signed/unsigned
+    integer type for pointers.  */
+  if (kind == KIND_IS_INTEGER_FOR_POINTER)
+    {
+      if (unsignedp)
+	{
+	  if (uintptr_type_node
+	      && mode == TYPE_MODE (uintptr_type_node))
+	    return uintptr_type_node;
+	}
+      else if (intptr_type_node
+	      && mode == TYPE_MODE (intptr_type_node))
+	    return intptr_type_node;
+    }
+
   if (mode == TYPE_MODE (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
 
@@ -2672,6 +2698,12 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
   return NULL_TREE;
 }
 
+tree
+c_common_type_for_mode (machine_mode mode, int unsignedp)
+{
+  return c_common_type_for_mode_kind (mode, unsignedp, KIND_IS_UNKNOWN);
+}
+
 tree
 c_common_unsigned_type (tree type)
 {
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index a4cd6786109..71561582bd7 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "fold-const.h"
 #include "wide-int-bitmask.h"
+#include "langhooks.h"
 
 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
@@ -881,6 +882,7 @@ extern bool c_common_handle_option (size_t, const char *, HOST_WIDE_INT, int,
 				    const struct cl_option_handlers *);
 extern bool default_handle_c_option (size_t, const char *, int);
 extern tree c_common_type_for_mode (machine_mode, int);
+extern tree c_common_type_for_mode_kind (machine_mode, int, type_kind);
 extern tree c_common_type_for_size (unsigned int, int);
 extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int,
 						int, int);
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index e103646b67e..66267e360e8 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -97,6 +97,8 @@ static const scoped_attribute_specs *const c_objc_attribute_table[] =
 #define LANG_HOOKS_SIMULATE_RECORD_DECL c_simulate_record_decl
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
+#undef LANG_HOOKS_TYPE_FOR_MODE_KIND
+#define LANG_HOOKS_TYPE_FOR_MODE_KIND c_common_type_for_mode_kind
 #undef LANG_HOOKS_TYPE_FOR_SIZE
 #define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
 #undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index ed29e65e4f3..2f96c63ba4f 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -152,6 +152,8 @@ static const scoped_attribute_specs *const cp_objcp_attribute_table[] =
 #define LANG_HOOKS_SIMULATE_RECORD_DECL cxx_simulate_record_decl
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
+#undef LANG_HOOKS_TYPE_FOR_MODE_KIND
+#define LANG_HOOKS_TYPE_FOR_MODE_KIND c_common_type_for_mode_kind
 #undef LANG_HOOKS_TYPE_FOR_SIZE
 #define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
 #undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index fc409ec08b9..6b96713d8f7 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -195,6 +195,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
 #define LANG_HOOKS_SIMULATE_ENUM_DECL	lhd_simulate_enum_decl
 #define LANG_HOOKS_SIMULATE_RECORD_DECL	lhd_simulate_record_decl
 #define LANG_HOOKS_CLASSIFY_RECORD	NULL
+#define LANG_HOOKS_TYPE_FOR_MODE_KIND	NULL
 #define LANG_HOOKS_TYPE_FOR_SIZE	lhd_type_for_size
 #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
 #define LANG_HOOKS_GENERIC_TYPE_P	hook_bool_const_tree_false
@@ -231,6 +232,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
   LANG_HOOKS_SIMULATE_RECORD_DECL, \
   LANG_HOOKS_CLASSIFY_RECORD, \
   LANG_HOOKS_TYPE_FOR_MODE, \
+  LANG_HOOKS_TYPE_FOR_MODE_KIND, \
   LANG_HOOKS_TYPE_FOR_SIZE, \
   LANG_HOOKS_GENERIC_TYPE_P, \
   LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 6eb5c1602f8..64151322281 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -34,6 +34,9 @@ typedef void (*lang_print_tree_hook) (FILE *, tree, int indent);
 enum classify_record
   { RECORD_IS_STRUCT, RECORD_IS_CLASS, RECORD_IS_INTERFACE };
 
+enum type_kind
+  { KIND_IS_UNKNOWN, KIND_IS_INTEGER_FOR_POINTER };
+
 class substring_loc;
 
 /* The following hooks are documented in langhooks.cc.  Must not be
@@ -87,6 +90,10 @@ struct lang_hooks_for_types
      mode.  */
   tree (*type_for_mode) (machine_mode, int);
 
+  /* Given MODE, UNSIGNEDP and KIND, return a suitable type-tree with
+     that mode.  */
+  tree (*type_for_mode_kind) (machine_mode, int, type_kind);
+
   /* Given PRECISION and UNSIGNEDP, return a suitable type-tree for an
      integer type with at least that precision.  */
   tree (*type_for_size) (unsigned, int);
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 295f70cb3f5..ba10aeb64da 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -942,7 +942,13 @@ default_stack_protect_guard (void)
       rtx x;
 
       if (targetm.stack_protect_guard_symbol_p ())
-	t = lang_hooks.types.type_for_mode (ptr_mode, 1);
+	{
+	  if (lang_hooks.types.type_for_mode_kind)
+	    t = lang_hooks.types.type_for_mode_kind
+	      (ptr_mode, 1, KIND_IS_INTEGER_FOR_POINTER);
+	  else
+	    t = lang_hooks.types.type_for_mode (ptr_mode, 1);
+	}
       else
 	t = ptr_type_node;
       t = build_decl (UNKNOWN_LOCATION,
-- 
2.54.0

Reply via email to