This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] C++: Fix three mangling bugs
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] C++: Fix three mangling bugs
- From: Chip Salzenberg <chip at valinux dot com>
- Date: Fri, 9 Jun 2000 15:38:40 -0700
The find_substitution() is awful, mangling "cin" as "_ZSi". The
discriminator_for_local_entity() fix I wonder about, but it avoids an
abort. The HOST_WIDE_INT patch fixes the template expansion bug I
reported earlier.
2000-06-09 Chip Salzenberg <chip@valinux.com>
* mangle.c (discriminator_for_local_entity): Don't crash if a
local class is NULL_TREE.
(find_substition): Don't mangle objects with typename
substitutions (e.g. "cin" as "Si").
Correctly mangle numbers up to max of unsigned HOST_WIDE_INT.
(write_number): Take HOST_WIDE_INT.
(write_unsigned_number): New function for unsigned HOST_WIDE_INT.
(write_integer_cst): Use it for unsigned constants.
(write_source_name): Pass HOST_WIDE_INT to write_number.
(write_discriminator): Likewise.
(write_template_param): Likewise.
(write_substitution): Likewise.
(mangle_thunk): Likewise.
(write_template_arg_literal): Likewise.
Also, use write_unsigned_number for hex strings.
(write_array_type): Use write_unsigned_number. Abort if too large.
Index: mangle.c
diff -u -2 -p -c -r1.6 mangle.c
cvs server: conflicting specifications of output style
*** mangle.c 2000/06/09 16:45:22 1.6
--- mangle.c 2000/06/09 22:30:03
*************** static void write_component PARAMS ((tre
*** 158,162 ****
static void write_unqualified_name PARAMS ((tree));
static void write_source_name PARAMS ((tree));
! static void write_number PARAMS ((int, int));
static void write_integer_cst PARAMS ((tree));
static void write_identifier PARAMS ((char *));
--- 158,163 ----
static void write_unqualified_name PARAMS ((tree));
static void write_source_name PARAMS ((tree));
! static void write_number PARAMS ((HOST_WIDE_INT, unsigned));
! static void write_unsigned_number PARAMS ((unsigned HOST_WIDE_INT, unsigned));
static void write_integer_cst PARAMS ((tree));
static void write_identifier PARAMS ((char *));
*************** find_substitution (node)
*** 442,446 ****
if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
{
! if (type)
{
/* If this is a type (i.e. a fully-qualified template-id),
--- 443,447 ----
if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
{
! if (TYPE_P (node))
{
/* If this is a type (i.e. a fully-qualified template-id),
*************** find_substitution (node)
*** 474,478 ****
/* Check for basic_{i,o,io}stream. */
! if (type
&& CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED
&& CLASS_TYPE_P (type)
--- 475,479 ----
/* Check for basic_{i,o,io}stream. */
! if (TYPE_P (node)
&& CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED
&& CLASS_TYPE_P (type)
*************** find_substitution (node)
*** 511,515 ****
/* Check for namespace std. */
! if (decl&& DECL_NAMESPACE_STD_P (decl))
{
write_string ("St");
--- 512,516 ----
/* Check for namespace std. */
! if (decl && DECL_NAMESPACE_STD_P (decl))
{
write_string ("St");
*************** write_source_name (identifier)
*** 914,918 ****
identifier = IDENTIFIER_TEMPLATE (identifier);
! write_number (IDENTIFIER_LENGTH (identifier), 10);
write_identifier (IDENTIFIER_POINTER (identifier));
}
--- 915,919 ----
identifier = IDENTIFIER_TEMPLATE (identifier);
! write_number ((HOST_WIDE_INT) IDENTIFIER_LENGTH (identifier), 10);
write_identifier (IDENTIFIER_POINTER (identifier));
}
*************** write_source_name (identifier)
*** 924,934 ****
static void
write_number (number, base)
! int number;
! int base;
{
- static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int n;
- int m = 1;
-
if (number < 0)
{
--- 925,931 ----
static void
write_number (number, base)
! HOST_WIDE_INT number;
! unsigned base;
{
if (number < 0)
{
*************** write_number (number, base)
*** 936,940 ****
number = -number;
}
!
n = number;
while (n >= base)
--- 933,948 ----
number = -number;
}
! write_unsigned_number (number, base);
! }
!
! static void
! write_unsigned_number (number, base)
! unsigned HOST_WIDE_INT number;
! unsigned base;
! {
! static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
! unsigned HOST_WIDE_INT n;
! unsigned HOST_WIDE_INT m = 1;
!
n = number;
while (n >= base)
*************** write_number (number, base)
*** 946,950 ****
while (m > 0)
{
! int digit = number / m;
write_char (digits[digit]);
number -= digit * m;
--- 954,958 ----
while (m > 0)
{
! unsigned digit = number / m;
write_char (digits[digit]);
number -= digit * m;
*************** write_integer_cst (cst)
*** 961,965 ****
tree cst;
{
! write_number (tree_low_cst (cst, TREE_UNSIGNED (TREE_TYPE (cst))), 10);
}
--- 969,979 ----
tree cst;
{
! if (TREE_UNSIGNED (TREE_TYPE (cst)))
! {
! my_friendly_assert (TREE_INT_CST_HIGH (cst) == 0, 20000609);
! write_unsigned_number (TREE_INT_CST_LOW (cst), 10);
! }
! else
! write_number (tree_low_cst (cst, 0), 10);
}
*************** discriminator_for_local_entity (entity)
*** 1049,1056 ****
/* Scan the list of local classes. */
entity = TREE_TYPE (entity);
! for (type = &VARRAY_TREE (local_classes, 0); *type != entity; ++type)
! if (TYPE_IDENTIFIER (*type) == TYPE_IDENTIFIER (entity)
! && TYPE_CONTEXT (*type) == TYPE_CONTEXT (entity))
! ++discriminator;
return discriminator;
--- 1063,1074 ----
/* Scan the list of local classes. */
entity = TREE_TYPE (entity);
! for (type = &VARRAY_TREE (local_classes, 0);
! *type && *type != entity;
! ++type)
! {
! if (TYPE_IDENTIFIER (*type) == TYPE_IDENTIFIER (entity)
! && TYPE_CONTEXT (*type) == TYPE_CONTEXT (entity))
! ++discriminator;
! }
return discriminator;
*************** write_discriminator (discriminator)
*** 1087,1091 ****
numbering starts at 0. */
if (discriminator > 1)
! write_number (discriminator - 2, 10);
}
}
--- 1105,1109 ----
numbering starts at 0. */
if (discriminator > 1)
! write_number ((HOST_WIDE_INT) (discriminator - 2), 10);
}
}
*************** write_template_arg_literal (value)
*** 1611,1617 ****
{
if (value == boolean_false_node || integer_zerop (value))
! write_number (0, 10);
else if (value == boolean_true_node)
! write_number (1, 10);
else
my_friendly_abort (20000412);
--- 1629,1635 ----
{
if (value == boolean_false_node || integer_zerop (value))
! write_number ((HOST_WIDE_INT) 0, 10);
else if (value == boolean_true_node)
! write_number ((HOST_WIDE_INT) 1, 10);
else
my_friendly_abort (20000412);
*************** write_template_arg_literal (value)
*** 1633,1638 ****
size_t i;
for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
! write_number (((unsigned char *)
! &TREE_REAL_CST (value))[i], 16);
#endif
}
--- 1651,1657 ----
size_t i;
for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
! write_unsigned_number ((unsigned HOST_WIDE_INT)
! ((unsigned char *)
! &TREE_REAL_CST (value))[i], 16);
#endif
}
*************** write_array_type (type)
*** 1733,1737 ****
max = TYPE_MAX_VALUE (index_type);
if (TREE_CODE (max) == INTEGER_CST)
! write_number (TREE_INT_CST_LOW (max) + 1, 10);
else
write_expression (TREE_OPERAND (max, 0));
--- 1752,1759 ----
max = TYPE_MAX_VALUE (index_type);
if (TREE_CODE (max) == INTEGER_CST)
! {
! my_friendly_assert (TREE_INT_CST_HIGH (max) == 0, 20000609);
! write_unsigned_number (TREE_INT_CST_LOW (max) + 1, 10);
! }
else
write_expression (TREE_OPERAND (max, 0));
*************** write_template_param (parm)
*** 1787,1791 ****
earliest template param denoted by `_'. */
if (parm_index > 0)
! write_number (parm_index - 1, 10);
write_char ('_');
}
--- 1809,1813 ----
earliest template param denoted by `_'. */
if (parm_index > 0)
! write_number ((HOST_WIDE_INT) (parm_index - 1), 10);
write_char ('_');
}
*************** write_substitution (seq_id)
*** 1832,1836 ****
write_char ('S');
if (seq_id > 0)
! write_number (seq_id - 1, 36);
write_char ('_');
}
--- 1854,1858 ----
write_char ('S');
if (seq_id > 0)
! write_number ((HOST_WIDE_INT) (seq_id - 1), 36);
write_char ('_');
}
*************** mangle_thunk (fn_decl, offset, vcall_off
*** 2064,2068 ****
/* For either flavor, write the offset to this. */
! write_number (offset, 10);
write_char ('_');
--- 2086,2090 ----
/* For either flavor, write the offset to this. */
! write_number ((HOST_WIDE_INT) offset, 10);
write_char ('_');
*************** mangle_thunk (fn_decl, offset, vcall_off
*** 2071,2075 ****
{
/* Virtual thunk. Write the vcall offset and base type name. */
! write_number (vcall_offset, 10);
write_char ('_');
}
--- 2093,2097 ----
{
/* Virtual thunk. Write the vcall offset and base type name. */
! write_number ((HOST_WIDE_INT) vcall_offset, 10);
write_char ('_');
}
--
Chip Salzenberg - a.k.a. - <chip@valinux.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
but he stepped in a wormhole and had to go in early." // MST3K