mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-19 09:49:11 +08:00
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:
parent
69c7591674
commit
6397d80b75
@ -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
|
||||
|
@ -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.
|
||||
|
107
gcc/cp/mangle.c
107
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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)}
|
||||
|
@ -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.
|
||||
|
13
gcc/testsuite/g++.dg/abi/mangle10.C
Normal file
13
gcc/testsuite/g++.dg/abi/mangle10.C
Normal 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 } }
|
10
gcc/testsuite/g++.dg/abi/mangle11.C
Normal file
10
gcc/testsuite/g++.dg/abi/mangle11.C
Normal 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" }
|
11
gcc/testsuite/g++.dg/abi/mangle12.C
Normal file
11
gcc/testsuite/g++.dg/abi/mangle12.C
Normal 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" }
|
12
gcc/testsuite/g++.dg/abi/mangle9.C
Normal file
12
gcc/testsuite/g++.dg/abi/mangle9.C
Normal 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 } }
|
Loading…
Reference in New Issue
Block a user