]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
SSP: Check UINTPTR_TYPE to get uintptr_t type
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 8 May 2026 04:20:02 +0000 (12:20 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 16 Jun 2026 21:23:15 +0000 (05:23 +0800)
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): If UINTPTR_TYPE
isn't NULL, 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 <hjl.tools@gmail.com>
gcc/targhooks.cc
gcc/tree.cc
gcc/tree.h

index 3b7d9f008e1d7feb30111fb819970c8aecd68152..670bc7aa22cdb0a79d6768d93adc12ec2337cd03 100644 (file)
@@ -941,8 +941,9 @@ 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 (UINTPTR_TYPE && targetm.stack_protect_guard_symbol_p ())
+       /* 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,
index 3f0d1c60574d35a4534019670ca8eb86e9be7377..90c8f2a35ea4716a43d5e7fe0f004d9fdd1cda2a 100644 (file)
@@ -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)
index 3e59bec1a946b3deb93785aeccb8a09eda84adb1..0774d6bd5a09f56680689cc2ece2ec68277c55eb 100644 (file)
@@ -5929,6 +5929,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);