On Thu, May 28, 2026 at 9:08 PM Jason Merrill <[email protected]> wrote:
>
> On 5/27/26 6:41 PM, 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.  Update default_stack_protect_guard to
> > check UINTPTR_TYPE to get unsigned integer type for uintptr_t instead.
> >
> > gcc/c-family/
> >
> > PR c/125226
> > * targhooks.cc (default_stack_protect_guard): Check UINTPTR_TYPE
> > to get unsigned integer type for uintptr_t.
> >
> > OK for mastter?
>
> If we're going to reuse the code from build_common_tree_nodes with a
> different string macro, let's factor it out into a function in tree.cc
> that gets called with SIZE_TYPE or UINTPTR_TYPE.
>
> Jason
>

Like this?

-- 
H.J.
---
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.  Update default_stack_protect_guard to
call unsigned_integer_tree_node_for_type with UINTPTR_TYPE to get unsigned
integer type for uintptr_t instead.

gcc/

PR c/125226
* targhooks.cc (default_stack_protect_guard): Call
unsigned_integer_tree_node_for_type with UINTPTR_TYPE to get
unsigned integer type for uintptr_t.
* tree.cc (unsigned_integer_tree_node_for_type): New function.
(build_common_tree_nodes): Call unsigned_integer_tree_node with
SIZE_TYPE to get unsigned integer type for size_t.
* tree.h (unsigned_integer_tree_node_for_type): New prototype.
From dd906f7ee3a30e8bab6052643a4ca8a831ddf476 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Fri, 8 May 2026 12:20:02 +0800
Subject: [PATCH v2] SSP: Check UINTPTR_TYPE to get uintptr_t type
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.  Update default_stack_protect_guard to
call unsigned_integer_tree_node_for_type with UINTPTR_TYPE to get unsigned
integer type for uintptr_t instead.

gcc/

	PR c/125226
	* targhooks.cc (default_stack_protect_guard): Call
	unsigned_integer_tree_node_for_type with UINTPTR_TYPE to get
	unsigned integer type for uintptr_t.
	* tree.cc (unsigned_integer_tree_node_for_type): New function.
	(build_common_tree_nodes): Call unsigned_integer_tree_node with
	SIZE_TYPE to get unsigned integer type for size_t.
	* tree.h (unsigned_integer_tree_node_for_type): New prototype.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/targhooks.cc |  3 ++-
 gcc/tree.cc      | 70 ++++++++++++++++++++++++++++--------------------
 gcc/tree.h       |  1 +
 3 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 295f70cb3f5..9a3b0a04958 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -942,7 +942,8 @@ default_stack_protect_guard (void)
       rtx x;
 
       if (targetm.stack_protect_guard_symbol_p ())
-	t = lang_hooks.types.type_for_mode (ptr_mode, 1);
+	/* Get unsigned integer type for uintptr_t.  */
+	t = unsigned_integer_tree_node_for_type (UINTPTR_TYPE);
       else
 	t = ptr_type_node;
       t = build_decl (UNKNOWN_LOCATION,
diff --git a/gcc/tree.cc b/gcc/tree.cc
index e3df004be97..47ee2424a3b 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9618,6 +9618,46 @@ build_atomic_base (tree type, unsigned int align)
   return t;
 }
 
+/* Return unsigned integer tree node for TYPE.  */
+
+tree
+unsigned_integer_tree_node_for_type (const char *type)
+{
+  tree type_node;
+
+  if (strcmp (type, "unsigned int") == 0)
+    type_node = unsigned_type_node;
+  else if (strcmp (type, "long unsigned int") == 0)
+    type_node = long_unsigned_type_node;
+  else if (strcmp (type, "long long unsigned int") == 0)
+    type_node = long_long_unsigned_type_node;
+  else if (strcmp (type, "short unsigned int") == 0)
+    type_node = short_unsigned_type_node;
+  else
+    {
+      int i;
+
+      type_node = nullptr;
+      for (i = 0; i < NUM_INT_N_ENTS; i++)
+	if (int_n_enabled_p[i])
+	  {
+	    char name[50], altname[50];
+	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
+	    sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);
+
+	    if (strcmp (name, type) == 0
+		|| strcmp (altname, type) == 0)
+	      {
+		type_node = int_n_trees[i].unsigned_type;
+	      }
+	  }
+      if (type_node == nullptr)
+	gcc_unreachable ();
+    }
+
+  return type_node;
+}
+
 /* Information about the _FloatN and _FloatNx types.  This must be in
    the same order as the corresponding TI_* enum values.  */
 const floatn_type_info floatn_nx_types[NUM_FLOATN_NX_TYPES] =
@@ -9688,35 +9728,7 @@ build_common_tree_nodes (bool signed_char)
   TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
 
   /* Define what type to use for size_t.  */
-  if (strcmp (SIZE_TYPE, "unsigned int") == 0)
-    size_type_node = unsigned_type_node;
-  else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
-    size_type_node = long_unsigned_type_node;
-  else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
-    size_type_node = long_long_unsigned_type_node;
-  else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
-    size_type_node = short_unsigned_type_node;
-  else
-    {
-      int i;
-
-      size_type_node = NULL_TREE;
-      for (i = 0; i < NUM_INT_N_ENTS; i++)
-	if (int_n_enabled_p[i])
-	  {
-	    char name[50], altname[50];
-	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
-	    sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);
-
-	    if (strcmp (name, SIZE_TYPE) == 0
-		|| strcmp (altname, SIZE_TYPE) == 0)
-	      {
-		size_type_node = int_n_trees[i].unsigned_type;
-	      }
-	  }
-      if (size_type_node == NULL_TREE)
-	gcc_unreachable ();
-    }
+  size_type_node = unsigned_integer_tree_node_for_type (SIZE_TYPE);
 
   /* Define what type to use for ptrdiff_t.  */
   if (strcmp (PTRDIFF_TYPE, "int") == 0)
diff --git a/gcc/tree.h b/gcc/tree.h
index 05400ada20b..4ec2fcf81a0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5903,6 +5903,7 @@ extern void init_ttree (void);
 extern void build_common_tree_nodes (bool);
 extern void build_common_builtin_nodes (void);
 extern void tree_cc_finalize (void);
+extern tree unsigned_integer_tree_node_for_type (const char *);
 extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
 extern tree build_nonstandard_boolean_type (unsigned HOST_WIDE_INT);
 extern tree build_bitint_type (unsigned HOST_WIDE_INT, int);
-- 
2.54.0

Reply via email to