diff options
author | Mark Mitchell <mark@codesourcery.com> | 2002-10-04 04:59:39 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2002-10-04 04:59:39 +0000 |
commit | 6397d80b752df0770438e1edbc1efd8773fbb7eb (patch) | |
tree | 2a6564ee9bc95c1a339ca2aa488debfeb614d0be | |
parent | 69c75916740ba75141accc68df66e17a486c11d1 (diff) | |
download | gcc-6397d80b752df0770438e1edbc1efd8773fbb7eb.zip gcc-6397d80b752df0770438e1edbc1efd8773fbb7eb.tar.gz gcc-6397d80b752df0770438e1edbc1efd8773fbb7eb.tar.bz2 |
re PR c++/8006 (ice in mangle_conv_op_name_for_type boost regression)
* doc/invoke.texi (-Wabi): Document mangling bug.
PR c++/8006
* mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
template parameters.
(globals): Add entity and need_abi_warning.
(decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
CLASSTYPE_TEMPLATE_INFO.
(is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
TYPE_TI_TEMPLATE.
(write_prefix): Handle typename types correctly.
(write_template_prefix): Handle template template parameters
correctly.
(start_mangling): Add entity parameter.
(finish_mangling): Warn about names whose mangling will change.
(mangle_decl_string): Adjust.
(mangle_type_string): Likewise.
(mangle_special_for_type): Likewise.
(mangle_ctor_vtbl_for_type): Likewise.
(mangle_thunk): Likewise.
(mangle_guard_variable): Likewise.
(mangle_ref_init_variable): Likewise.
PR c++/8006
* g++.dg/abi/mangle9.C: New test.
* g++.dg/abi/mangle10.C: New test.
* g++.dg/abi/mangle11.C: New test.
* g++.dg/abi/mangle12.C: New test.
From-SVN: r57799
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 107 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle10.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle11.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle12.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle9.C | 12 |
9 files changed, 168 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ffd1b53..a664139 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2002-10-03 Mark Mitchell <mark@codesourcery.com> + + * doc/invoke.texi (-Wabi): Document mangling bug. + 2002-10-04 Alan Modra <amodra@bigpond.net.au> * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Use a diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 521b497..f10a564 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,26 @@ +2002-10-03 Mark Mitchell <mark@codesourcery.com> + + PR c++/8006 + * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template + template parameters. + (globals): Add entity and need_abi_warning. + (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not + CLASSTYPE_TEMPLATE_INFO. + (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not + TYPE_TI_TEMPLATE. + (write_prefix): Handle typename types correctly. + (write_template_prefix): Handle template template parameters + correctly. + (start_mangling): Add entity parameter. + (finish_mangling): Warn about names whose mangling will change. + (mangle_decl_string): Adjust. + (mangle_type_string): Likewise. + (mangle_special_for_type): Likewise. + (mangle_ctor_vtbl_for_type): Likewise. + (mangle_thunk): Likewise. + (mangle_guard_variable): Likewise. + (mangle_ref_init_variable): Likewise. + 2002-10-02 Mark Mitchell <mark@codesourcery.com> PR c++/7188. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c7bd312..76fd5f7 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -80,10 +80,11 @@ that hard to distinguish A<T> from A, where A<T> is the type as instantiated outside of the template, and A is the type used without parameters inside the template. */ -#define CLASSTYPE_TEMPLATE_ID_P(NODE) \ - (TYPE_LANG_SPECIFIC (NODE) != NULL \ - && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ - && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))) +#define CLASSTYPE_TEMPLATE_ID_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) != NULL \ + && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ + || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ + && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))))) /* Things we only need one of. This module is not reentrant. */ static struct globals @@ -95,10 +96,17 @@ static struct globals we've seen them. */ varray_type substitutions; + /* 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; } G; /* Indices into subst_identifiers. These are identifiers used in @@ -192,8 +200,8 @@ static const char *mangle_decl_string PARAMS ((tree)); /* Control functions. */ -static inline void start_mangling PARAMS ((void)); -static inline const char *finish_mangling PARAMS ((void)); +static inline void start_mangling (tree); +static inline const char *finish_mangling (bool); static tree mangle_special_for_type PARAMS ((tree, const char *)); /* Foreign language functions. */ @@ -250,7 +258,7 @@ decl_is_template_id (decl, template_info) if (template_info != NULL) /* For a templated TYPE_DECL, the template info is hanging off the type. */ - *template_info = CLASSTYPE_TEMPLATE_INFO (type); + *template_info = TYPE_TEMPLATE_INFO (type); return 1; } } @@ -398,8 +406,8 @@ is_std_substitution (node, index) return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_TEMPLATE_INFO (type) - && (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) + && TYPE_TEMPLATE_INFO (type) + && (DECL_NAME (TYPE_TI_TEMPLATE (type)) == subst_identifiers[index])); } @@ -837,7 +845,8 @@ write_nested_name (decl) write_char ('E'); } -/* <prefix> ::= <prefix> <unqualified-name>> +/* <prefix> ::= <prefix> <unqualified-name> + ::= <template-param> ::= <template-prefix> <template-args> ::= # empty ::= <substitution> */ @@ -860,7 +869,6 @@ write_prefix (node) return; if (DECL_P (node)) - /* Node is a decl. */ { /* If this is a function decl, that means we've hit function scope, so this prefix must be for a local name. In this @@ -874,14 +882,22 @@ write_prefix (node) decl_is_template_id (decl, &template_info); } else - /* Node is a type. */ { + /* Node is a type. */ decl = TYPE_NAME (node); if (CLASSTYPE_TEMPLATE_ID_P (node)) - template_info = CLASSTYPE_TEMPLATE_INFO (node); + template_info = TYPE_TEMPLATE_INFO (node); } - if (template_info != NULL) + /* In G++ 3.2, the name of the template parameter was used. */ + if (TREE_CODE (node) == TEMPLATE_TYPE_PARM + && !abi_version_at_least (2)) + G.need_abi_warning = true; + + if (TREE_CODE (node) == TEMPLATE_TYPE_PARM + && abi_version_at_least (2)) + write_template_param (node); + else if (template_info != NULL) /* Templated. */ { write_template_prefix (decl); @@ -898,6 +914,7 @@ write_prefix (node) } /* <template-prefix> ::= <prefix> <template component> + ::= <template-param> ::= <substitution> */ static void @@ -917,7 +934,7 @@ write_template_prefix (node) if (decl_is_template_id (decl, &template_info)) template = TI_TEMPLATE (template_info); else if (CLASSTYPE_TEMPLATE_ID_P (type)) - template = CLASSTYPE_TI_TEMPLATE (type); + template = TYPE_TI_TEMPLATE (type); else /* Oops, not a template. */ abort (); @@ -952,8 +969,19 @@ write_template_prefix (node) if (find_substitution (substitution)) return; - write_prefix (context); - write_unqualified_name (decl); + /* In G++ 3.2, the name of the template template parameter was used. */ + if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM + && !abi_version_at_least (2)) + G.need_abi_warning = true; + + if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM + && abi_version_at_least (2)) + write_template_param (TREE_TYPE (template)); + else + { + write_prefix (context); + write_unqualified_name (decl); + } add_substitution (substitution); } @@ -2168,20 +2196,29 @@ write_substitution (seq_id) write_char ('_'); } -/* Start mangling a new name or type. */ +/* Start mangling ENTITY. */ static inline void -start_mangling () +start_mangling (tree entity) { + G.entity = entity; + G.need_abi_warning = false; VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions"); obstack_free (&G.name_obstack, obstack_base (&G.name_obstack)); } -/* Done with mangling. Return the generated mangled name. */ +/* Done with mangling. Return the generated mangled name. If WARN is + true, and the name of G.entity will be mangled differently in a + future version of the ABI, issue a warning. */ static inline const char * -finish_mangling () +finish_mangling (bool warn) { + if (warn_abi && warn && G.need_abi_warning) + warning ("the mangled name of `%D' will change in a future " + "version of GCC", + G.entity); + /* Clear all the substitutions. */ G.substitutions = 0; @@ -2216,7 +2253,7 @@ mangle_decl_string (decl) { const char *result; - start_mangling (); + start_mangling (decl); if (TREE_CODE (decl) == TYPE_DECL) write_type (TREE_TYPE (decl)); @@ -2243,7 +2280,7 @@ mangle_decl_string (decl) write_string (" *INTERNAL* "); } - result = finish_mangling (); + result = finish_mangling (/*warn=*/true); if (DEBUG_MANGLE) fprintf (stderr, "mangle_decl_string = '%s'\n\n", result); return result; @@ -2268,9 +2305,9 @@ mangle_type_string (type) { const char *result; - start_mangling (); + start_mangling (type); write_type (type); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); return result; @@ -2298,7 +2335,7 @@ mangle_special_for_type (type, code) /* We don't have an actual decl here for the special component, so we can't just process the <encoded-name>. Instead, fake it. */ - start_mangling (); + start_mangling (type); /* Start the mangling. */ write_string ("_Z"); @@ -2306,7 +2343,7 @@ mangle_special_for_type (type, code) /* Add the type. */ write_type (type); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_special_for_type = %s\n\n", result); @@ -2373,7 +2410,7 @@ mangle_ctor_vtbl_for_type (type, binfo) { const char *result; - start_mangling (); + start_mangling (type); write_string ("_Z"); write_string ("TC"); @@ -2382,7 +2419,7 @@ mangle_ctor_vtbl_for_type (type, binfo) write_char ('_'); write_type (BINFO_TYPE (binfo)); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", result); return get_identifier (result); @@ -2406,7 +2443,7 @@ mangle_thunk (fn_decl, offset, vcall_offset) { const char *result; - start_mangling (); + start_mangling (fn_decl); write_string ("_Z"); /* The <special-name> for virtual thunks is Tv, for non-virtual @@ -2432,7 +2469,7 @@ mangle_thunk (fn_decl, offset, vcall_offset) /* Scoped name. */ write_encoding (fn_decl); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_thunk = %s\n\n", result); return get_identifier (result); @@ -2484,7 +2521,7 @@ tree mangle_guard_variable (variable) tree variable; { - start_mangling (); + start_mangling (variable); write_string ("_ZGV"); if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0) /* The name of a guard variable for a reference temporary should refer @@ -2492,7 +2529,7 @@ mangle_guard_variable (variable) write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); else write_name (variable, /*ignore_local_scope=*/0); - return get_identifier (finish_mangling ()); + return get_identifier (finish_mangling (/*warn=*/false)); } /* Return an identifier for the name of a temporary variable used to @@ -2503,10 +2540,10 @@ tree mangle_ref_init_variable (variable) tree variable; { - start_mangling (); + start_mangling (variable); write_string ("_ZGR"); write_name (variable, /*ignore_local_scope=*/0); - return get_identifier (finish_mangling ()); + return get_identifier (finish_mangling (/*warn=*/false)); } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 607a08a..65aa2a0 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1565,6 +1565,21 @@ G++ will place the @code{A} base class of @code{C} at a non-zero offset; it should be placed at offset zero. G++ mistakenly believes that the @code{A} data member of @code{B} is already at offset zero. +@item +Names of template functions whose types involve @code{typename} or +template template parameters can be mangled incorrectly. + +@smallexample +template <typename Q> +void f(typename Q::X) @{@} + +template <template <typename> class Q> +void f(typename Q<int>::X) @{@} +@end smallexample + +@noindent +Instantions of these templates may be mangled incorrectly. + @end itemize @item -Wctor-dtor-privacy @r{(C++ only)} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 412533c..6162206 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2002-10-03 Mark Mitchell <mark@codesourcery.com> + + PR c++/8006 + * g++.dg/abi/mangle9.C: New test. + * g++.dg/abi/mangle10.C: New test. + * g++.dg/abi/mangle11.C: New test. + * g++.dg/abi/mangle12.C: New test. + 2002-10-02 Mark Mitchell <mark@codesourcery.com> PR c++/7188. diff --git a/gcc/testsuite/g++.dg/abi/mangle10.C b/gcc/testsuite/g++.dg/abi/mangle10.C new file mode 100644 index 0000000..d5782ba --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle10.C @@ -0,0 +1,13 @@ +// { dg-options "-fabi-version=0" } + +template <template <typename> class Q> +void f (typename Q<int>::X) {} + +template <typename Q> +struct S { + typedef int X; +}; + +template void f<S> (int); + +// { dg-final { scan-assembler _Z1fI1SEvNT_IiE1XE } } diff --git a/gcc/testsuite/g++.dg/abi/mangle11.C b/gcc/testsuite/g++.dg/abi/mangle11.C new file mode 100644 index 0000000..f715117 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle11.C @@ -0,0 +1,10 @@ +// { dg-options "-Wabi" } + +template <typename Q> +void f (typename Q::X) {} + +struct S { + typedef int X; +}; + +template void f<S> (int); // { dg-warning "mangle" } diff --git a/gcc/testsuite/g++.dg/abi/mangle12.C b/gcc/testsuite/g++.dg/abi/mangle12.C new file mode 100644 index 0000000..772b58b --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle12.C @@ -0,0 +1,11 @@ +// { dg-options "-Wabi" } + +template <template <typename> class Q> +void f (typename Q<int>::X) {} + +template <typename Q> +struct S { + typedef int X; +}; + +template void f<S> (int); // { dg-warning "mangle" } diff --git a/gcc/testsuite/g++.dg/abi/mangle9.C b/gcc/testsuite/g++.dg/abi/mangle9.C new file mode 100644 index 0000000..f3ededf --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle9.C @@ -0,0 +1,12 @@ +// { dg-options "-fabi-version=0" } + +template <typename Q> +void f (typename Q::X) {} + +struct S { + typedef int X; +}; + +template void f<S> (int); + +// { dg-final { scan-assembler _Z1fI1SEvNT_1XE } } |