Commit 5fd80fbc by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/13241 ([ABI] Incorrect mangling of template arguments)

cp:
	PR c++/13241
	C++ ABI change. Mangling of symbols in expressions.
	* mangle.c (write_mangled_name): Add top_level flag. Rework for
	nested and unnested mangling. Deal with abi version 1 and version
	2 differences.
	(write_expression): Adjust write_mangled_name call.
	(mangle_decl_string): Use write_mangled_name for all non-type decls.
testsuite:
	PR c++/13241
	* g++.dg/abi/mangle18-1.C: New test.
	* g++.dg/abi/mangle18-2.C: New test.

From-SVN: r74628
parent 209db2bf
2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
PR c++/13241
C++ ABI change. Mangling of symbols in expressions.
* mangle.c (write_mangled_name): Add top_level flag. Rework for
nested and unnested mangling. Deal with abi version 1 and version
2 differences.
(write_expression): Adjust write_mangled_name call.
(mangle_decl_string): Use write_mangled_name for all non-type decls.
2003-12-14 Mark Mitchell <mark@codesourcery.com> 2003-12-14 Mark Mitchell <mark@codesourcery.com>
PR c++/10779 PR c++/10779
......
...@@ -158,7 +158,7 @@ static void mangle_call_offset (const tree, const tree); ...@@ -158,7 +158,7 @@ static void mangle_call_offset (const tree, const tree);
/* Functions for emitting mangled representations of things. */ /* Functions for emitting mangled representations of things. */
static void write_mangled_name (const tree); static void write_mangled_name (const tree, bool);
static void write_encoding (const tree); static void write_encoding (const tree);
static void write_name (tree, const int); static void write_name (tree, const int);
static void write_unscoped_name (const tree); static void write_unscoped_name (const tree);
...@@ -602,27 +602,66 @@ find_substitution (tree node) ...@@ -602,27 +602,66 @@ find_substitution (tree node)
} }
/* <mangled-name> ::= _Z <encoding> */ /* TOP_LEVEL is true, if this is being called at outermost level of
mangling. It should be false when mangling a decl appearing in an
expression within some other mangling.
<mangled-name> ::= _Z <encoding> */
static inline void static inline void
write_mangled_name (const tree decl) write_mangled_name (const tree decl, bool top_level)
{ {
MANGLE_TRACE_TREE ("mangled-name", decl); MANGLE_TRACE_TREE ("mangled-name", decl);
if (DECL_LANG_SPECIFIC (decl) if (/* The names of `extern "C"' functions are not mangled. */
&& DECL_EXTERN_C_FUNCTION_P (decl) DECL_EXTERN_C_FUNCTION_P (decl)
&& ! DECL_OVERLOADED_OPERATOR_P (decl)) /* But overloaded operator names *are* mangled. */
/* The standard notes: && !DECL_OVERLOADED_OPERATOR_P (decl))
"The <encoding> of an extern "C" function is treated like {
global-scope data, i.e. as its <source-name> without a type." unmangled_name:;
We cannot write overloaded operators that way though,
because it contains characters invalid in assembler. */ if (top_level)
write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
else
{
/* The standard notes: "The <encoding> of an extern "C"
function is treated like global-scope data, i.e. as its
<source-name> without a type." We cannot write
overloaded operators that way though, because it contains
characters invalid in assembler. */
if (abi_version_at_least (2))
write_string ("_Z");
else
G.need_abi_warning = true;
write_source_name (DECL_NAME (decl)); write_source_name (DECL_NAME (decl));
}
}
else if (TREE_CODE (decl) == VAR_DECL
/* The names of global variables aren't mangled. */
&& (CP_DECL_CONTEXT (decl) == global_namespace
/* And neither are `extern "C"' variables. */
|| DECL_EXTERN_C_P (decl)))
{
if (top_level || abi_version_at_least (2))
goto unmangled_name;
else
{
G.need_abi_warning = true;
goto mangled_name;
}
}
else else
/* C++ name; needs to be mangled. */
{ {
mangled_name:;
write_string ("_Z"); write_string ("_Z");
write_encoding (decl); write_encoding (decl);
if (DECL_LANG_SPECIFIC (decl)
&& (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
|| DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
/* We need a distinct mangled name for these entities, but
we should never actually output it. So, we append some
characters the assembler won't like. */
write_string (" *INTERNAL* ");
} }
} }
...@@ -1895,7 +1934,7 @@ write_expression (tree expr) ...@@ -1895,7 +1934,7 @@ write_expression (tree expr)
if (code == CONST_DECL) if (code == CONST_DECL)
G.need_abi_warning = 1; G.need_abi_warning = 1;
write_char ('L'); write_char ('L');
write_mangled_name (expr); write_mangled_name (expr, false);
write_char ('E'); write_char ('E');
} }
else if (TREE_CODE (expr) == SIZEOF_EXPR else if (TREE_CODE (expr) == SIZEOF_EXPR
...@@ -2365,28 +2404,8 @@ mangle_decl_string (const tree decl) ...@@ -2365,28 +2404,8 @@ mangle_decl_string (const tree decl)
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
write_type (TREE_TYPE (decl)); write_type (TREE_TYPE (decl));
else if (/* The names of `extern "C"' functions are not mangled. */
(DECL_EXTERN_C_FUNCTION_P (decl)
/* But overloaded operator names *are* mangled. */
&& !DECL_OVERLOADED_OPERATOR_P (decl))
/* The names of global variables aren't mangled either. */
|| (TREE_CODE (decl) == VAR_DECL
&& CP_DECL_CONTEXT (decl) == global_namespace)
/* And neither are `extern "C"' variables. */
|| (TREE_CODE (decl) == VAR_DECL
&& DECL_EXTERN_C_P (decl)))
write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
else else
{ write_mangled_name (decl, true);
write_mangled_name (decl);
if (DECL_LANG_SPECIFIC (decl)
&& (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
|| DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
/* We need a distinct mangled name for these entities, but
we should never actually output it. So, we append some
characters the assembler won't like. */
write_string (" *INTERNAL* ");
}
result = finish_mangling (/*warn=*/true); result = finish_mangling (/*warn=*/true);
if (DEBUG_MANGLE) if (DEBUG_MANGLE)
......
2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
PR c++/13241
* g++.dg/abi/mangle18-1.C: New test.
* g++.dg/abi/mangle18-2.C: New test.
2003-12-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> 2003-12-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
PR optimization/10312 PR optimization/10312
......
// { dg-do compile }
// { dg-options "-fabi-version=2" }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
// PR 13241
// mangled template arguments that are external objects incorrectly
extern "C" void Foo ();
namespace NMS
{
extern "C" int V;
}
template <void (*)()> struct S {};
template <int *> struct T {};
void f (S<Foo>){}
// { dg-final { scan-assembler "\n_Z1f1SIXadL_Z3FooEEE:" } }
void g (T<&NMS::V>){}
// { dg-final { scan-assembler "\n_Z1g1TIXadL_Z1VEEE:" } }
// { dg-do compile }
// { dg-options "-fabi-version=1 -Wabi" }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
// PR 13241
// mangled template arguments that are external objects incorrectly
extern "C" void Foo ();
namespace NMS
{
extern "C" int V;
}
template <void (*)()> struct S {};
template <int *> struct T {};
void f (S<Foo>){} // { dg-warning "mangled name" }
// { dg-final { scan-assembler "\n_Z1f1SIXadL3FooEEE:" } }
void g (T<&NMS::V>){} // { dg-warning "mangled name" }
// { dg-final { scan-assembler "\n_Z1g1TIXadL_ZN3NMS1VEEEE:" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment