From: H.J. Lu Date: Fri, 8 May 2026 04:20:02 +0000 (+0800) Subject: SSP: Check UINTPTR_TYPE to get uintptr_t type X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fa69425e64d9850b0e64a53b15545bdcdbedcd69;p=thirdparty%2Fgcc.git SSP: Check UINTPTR_TYPE to get uintptr_t type 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 --- diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 3b7d9f008e1..670bc7aa22c 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -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, diff --git a/gcc/tree.cc b/gcc/tree.cc index 3f0d1c60574..90c8f2a35ea 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 3e59bec1a94..0774d6bd5a0 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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);