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