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
This commit is contained in:
Mark Mitchell 2002-10-04 04:59:39 +00:00 committed by Mark Mitchell
parent 69c7591674
commit 6397d80b75
9 changed files with 168 additions and 35 deletions

View File

@ -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

View File

@ -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.

View File

@ -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));
}

View File

@ -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)}

View File

@ -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.

View File

@ -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 } }

View File

@ -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" }

View File

@ -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" }

View File

@ -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 } }