diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2003-12-15 11:57:30 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2003-12-15 11:57:30 +0000 |
commit | 5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd (patch) | |
tree | 1052eda794a2870ee8942d5cf1a622bd1affe197 /gcc | |
parent | 209db2bf05a5830792bc1a2f06c8fedf21285304 (diff) | |
download | gcc-5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd.zip gcc-5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd.tar.gz gcc-5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 91 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle18-1.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle18-2.C | 23 |
5 files changed, 117 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 732273e..5d70a54 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +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 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index ff8e6ea..a20757e 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d44759f..2d2d7cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +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 diff --git a/gcc/testsuite/g++.dg/abi/mangle18-1.C b/gcc/testsuite/g++.dg/abi/mangle18-1.C new file mode 100644 index 0000000..2e7b3a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle18-1.C @@ -0,0 +1,23 @@ +// { 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:" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle18-2.C b/gcc/testsuite/g++.dg/abi/mangle18-2.C new file mode 100644 index 0000000..be2b6b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle18-2.C @@ -0,0 +1,23 @@ +// { 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:" } } |