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>
PR c++/10779
......
......@@ -158,7 +158,7 @@ static void mangle_call_offset (const tree, const tree);
/* 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_name (tree, const int);
static void write_unscoped_name (const tree);
......@@ -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
write_mangled_name (const tree decl)
write_mangled_name (const tree decl, bool top_level)
{
MANGLE_TRACE_TREE ("mangled-name", decl);
if (DECL_LANG_SPECIFIC (decl)
&& DECL_EXTERN_C_FUNCTION_P (decl)
&& ! DECL_OVERLOADED_OPERATOR_P (decl))
/* 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. */
write_source_name (DECL_NAME (decl));
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))
{
unmangled_name:;
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));
}
}
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
/* C++ name; needs to be mangled. */
{
mangled_name:;
write_string ("_Z");
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)
if (code == CONST_DECL)
G.need_abi_warning = 1;
write_char ('L');
write_mangled_name (expr);
write_mangled_name (expr, false);
write_char ('E');
}
else if (TREE_CODE (expr) == SIZEOF_EXPR
......@@ -2365,29 +2404,9 @@ mangle_decl_string (const tree decl)
if (TREE_CODE (decl) == 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
{
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* ");
}
write_mangled_name (decl, true);
result = finish_mangling (/*warn=*/true);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_decl_string = '%s'\n\n", result);
......
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>
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