diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-06-17 16:58:19 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-06-17 16:58:19 +0000 |
commit | ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4 (patch) | |
tree | 9158221fab15fe3ae9e6c048a33b2f599faa86c7 /gcc/cp/mangle.c | |
parent | 8207b189e50ec5350d3ab72b397ee139282b4e9d (diff) | |
download | gcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.zip gcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.tar.gz gcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.tar.bz2 |
re PR c++/11105 ([3.3/3.4 regression of sorts] ICE in mangle_conv_op_name_for_type)
PR c++/11105
* cp-tree.h (DECL_CONV_FN_TYPE): New method.
* mangle.c (struct globals): Remove internal_mangling_p.
(write_unqualified_name): Use DECL_CONV_FN_TYPE.
(write_template_parm): Don't write out the level number.
(conv_type_names): New variable.
(hash_type): New function.
(compare_type): Likewise.
(mangle_conv_op_name_for_type): Don't try to mangle conversion
operator names.
* search.c (lookup_conversion_operator): New function.
(lookup_fnfields_1): Use it.
PR c++/11105
* g++.dg/abi/conv1.C: Remove it.
* g++.dg/template/conv7.C: New test.
* g++.dg/template/conv8.C: Likewise.
* g++.old-deja/g++.ext/pretty2.C: Do not test __FUNCTION__ for a
conversion operator.
From-SVN: r68095
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r-- | gcc/cp/mangle.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c0d31ba..4c53662 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -102,11 +102,6 @@ static struct globals /* The entity that is being mangled. */ tree entity; - /* We are mangling an internal symbol. It is important to keep those - involving template parmeters distinct by distinguishing their level - and, for non-type parms, their type. */ - bool internal_mangling_p; - /* True if the mangling will be different in a future version of the ABI. */ bool need_abi_warning; @@ -1006,7 +1001,7 @@ write_unqualified_name (const tree decl) type = TREE_TYPE (fn_type); } else - type = TREE_TYPE (DECL_NAME (decl)); + type = DECL_CONV_FN_TYPE (decl); write_conversion_operator_name (type); } else if (DECL_OVERLOADED_OPERATOR_P (decl)) @@ -2250,15 +2245,6 @@ write_template_param (const tree parm) if (parm_index > 0) write_unsigned_number (parm_index - 1); write_char ('_'); - if (G.internal_mangling_p) - { - if (parm_level > 0) - write_unsigned_number (parm_level - 1); - write_char ('_'); - if (parm_type) - write_type (parm_type); - write_char ('_'); - } } /* <template-template-param> @@ -2600,6 +2586,28 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset, return get_identifier (result); } +/* This hash table maps TYPEs to the IDENTIFIER for a conversion + operator to TYPE. The nodes are TREE_LISTs whose TREE_PURPOSE is + the TYPE and whose TREE_VALUE is the IDENTIFIER. */ + +static GTY ((param_is (union tree_node))) htab_t conv_type_names; + +/* Hash a node (VAL1) in the table. */ + +static hashval_t +hash_type (const void *val) +{ + return htab_hash_pointer (TREE_PURPOSE (*((tree *) val))); +} + +/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */ + +static int +compare_type (const void *val1, const void *val2) +{ + return TREE_PURPOSE ((tree) val1) == (tree) val2; +} + /* Return an identifier for the mangled unqualified name for a conversion operator to TYPE. This mangling is not specified by the ABI spec; it is only used internally. */ @@ -2607,33 +2615,22 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset, tree mangle_conv_op_name_for_type (const tree type) { + void **slot; tree identifier; - const char *mangled_type; - char *op_name; + char buffer[64]; - /* Build the internal mangling for TYPE. */ - G.internal_mangling_p = true; - mangled_type = mangle_type_string (type); - G.internal_mangling_p = false; - - /* Allocate a temporary buffer for the complete name. */ - op_name = concat ("operator ", mangled_type, NULL); - /* Find or create an identifier. */ - identifier = get_identifier (op_name); - /* Done with the temporary buffer. */ - free (op_name); - - /* It had better be a unique mangling for the type. */ - if (IDENTIFIER_TYPENAME_P (identifier) - && !same_type_p (type, TREE_TYPE (identifier))) - { - /* In G++ 3.2, the name mangling scheme was ambiguous. In later - versions of the ABI, this problem has been fixed. */ - if (abi_version_at_least (2)) - abort (); - error ("due to a defect in the G++ 3.2 ABI, G++ has assigned the " - "same mangled name to two different types"); - } + if (conv_type_names == NULL) + conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL); + + slot = htab_find_slot_with_hash (conv_type_names, type, + htab_hash_pointer (type), INSERT); + if (*slot) + return TREE_VALUE ((tree) *slot); + + /* Create a unique name corresponding to TYPE. */ + sprintf (buffer, "operator %d\n", htab_elements (conv_type_names)); + identifier = get_identifier (buffer); + *slot = build_tree_list (type, identifier); /* Set bits on the identifier so we know later it's a conversion. */ IDENTIFIER_OPNAME_P (identifier) = 1; |