aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2003-12-15 11:57:30 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2003-12-15 11:57:30 +0000
commit5fd80fbc3ba36fba8c0ec6c0f8509ff44e0a9fdd (patch)
tree1052eda794a2870ee8942d5cf1a622bd1affe197 /gcc
parent209db2bf05a5830792bc1a2f06c8fedf21285304 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/mangle.c91
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle18-1.C23
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle18-2.C23
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:" } }