From 5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 15 Dec 2003 11:57:30 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 10 +++ gcc/cp/mangle.c | 91 ++++++++++++++++----------- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/abi/mangle18-1.C | 23 +++++++ gcc/testsuite/g++.dg/abi/mangle18-2.C | 23 +++++++ 5 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/mangle18-1.C create mode 100644 gcc/testsuite/g++.dg/abi/mangle18-2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 732273e2edf..5d70a54f5a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2003-12-15 Nathan Sidwell + + 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 PR c++/10779 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index ff8e6eaee71..a20757e0c7e 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) } -/* ::= _Z */ +/* 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. + + ::= _Z */ 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 of an extern "C" function is treated like - global-scope data, i.e. as its 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 of an extern "C" + function is treated like global-scope data, i.e. as its + 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 d44759f3cd5..2d2d7cccf3a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-12-15 Nathan Sidwell + + PR c++/13241 + * g++.dg/abi/mangle18-1.C: New test. + * g++.dg/abi/mangle18-2.C: New test. + 2003-12-15 Zdenek Dvorak 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 00000000000..2e7b3a8382e --- /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 + +// PR 13241 +// mangled template arguments that are external objects incorrectly + +extern "C" void Foo (); +namespace NMS +{ + extern "C" int V; +} + +template struct S {}; +template struct T {}; + +void f (S){} +// { 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 00000000000..be2b6b5e434 --- /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 + +// PR 13241 +// mangled template arguments that are external objects incorrectly + +extern "C" void Foo (); +namespace NMS +{ + extern "C" int V; +} + +template struct S {}; +template struct T {}; + +void f (S){} // { 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:" } } -- 2.30.2