aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-11-02 14:43:46 +0000
committerJakub Jelinek <jakub@redhat.com>2009-11-02 14:43:46 +0000
commitb36b563f1576b67a25b26bef40a77121895faa8c (patch)
tree49a070246a4bd143ab2cef548354ec86232c5522
parent542bf15772e2e1d6d45087fa77316f096a100974 (diff)
svn merge -r153788:153789 svn+ssh://gcc.gnu.org/svn/gcc/trunk
svn merge -r153767:153768 svn+ssh://gcc.gnu.org/svn/gcc/trunk git-svn-id: https://gcc.gnu.org/svn/gcc/branches/redhat/gcc-4_4-branch@153811 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/mangle.c45
-rw-r--r--gcc/cp/name-lookup.c9
-rw-r--r--gcc/cp/rtti.c30
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid9.C21
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/libsupc++/tinfo.cc3
-rw-r--r--libstdc++-v3/libsupc++/tinfo2.cc3
-rw-r--r--libstdc++-v3/libsupc++/typeinfo9
11 files changed, 93 insertions, 55 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4e78ba7f5ad..9fcbdc6ecf9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -4,6 +4,22 @@
* call.c (compare_ics): Avoid bad union use when
comparing two ck_lists.
+2009-10-31 Jason Merrill <jason@redhat.com>
+
+ * rtti.c (tinfo_name): Fix lengths for private case.
+
+2009-10-30 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Revert r149964.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Insert '*' in front of private names.
+ (tinfo_base_init): Use it.
+
2009-10-26 Jakub Jelinek <jakub@redhat.com>
PR debug/41828
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index adea38d0782..1803f20dde3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4302,7 +4302,6 @@ extern void adjust_clone_args (tree);
/* decl.c */
extern tree poplevel (int, int, int);
extern void insert_block (tree);
-extern tree get_anonymous_namespace_name (void);
extern tree pushdecl (tree);
extern tree pushdecl_maybe_friend (tree, bool);
extern void cxx_init_decl_processing (void);
@@ -5034,7 +5033,7 @@ extern tree merge_exception_specifiers (tree, tree);
/* in mangle.c */
extern void init_mangle (void);
extern void mangle_decl (tree);
-extern const char *mangle_type_string_for_rtti (tree);
+extern const char *mangle_type_string (tree);
extern tree mangle_typeinfo_for_type (tree);
extern tree mangle_typeinfo_string_for_type (tree);
extern tree mangle_vtbl_for_type (tree);
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index f1aa21af5fa..b7524636f83 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -106,10 +106,6 @@ typedef struct globals GTY(())
static GTY (()) globals G;
-/* Whether or not to pretend that a static function is in an anonymous
- namespace. */
-static bool fake_anon_scope;
-
/* The obstack on which we build mangled names. */
static struct obstack *mangle_obstack;
@@ -726,20 +722,6 @@ write_encoding (const tree decl)
}
}
-/* Since we now use strcmp to compare typeinfos on all targets because of
- the RTLD_LOCAL problem, we need to munge the typeinfo name used for
- local classes of static functions to fix g++.dg/abi/local1.C. We do
- that by pretending that the function is in an anonymous namespace. */
-
-static bool
-needs_fake_anon (const_tree decl)
-{
- /* Pretend there's an anonymous namespace right around a static
- function if we're mangling for RTTI. */
- return (fake_anon_scope && !TREE_PUBLIC (decl)
- && TREE_CODE (decl) == FUNCTION_DECL);
-}
-
/* <name> ::= <unscoped-name>
::= <unscoped-template-name> <template-args>
::= <nested-name>
@@ -768,18 +750,13 @@ write_name (tree decl, const int ignore_local_scope)
else
context = CP_DECL_CONTEXT (decl);
- gcc_assert (context != NULL_TREE);
-
- /* If we need a fake anonymous namespace, force the nested name path. */
- if (needs_fake_anon (decl) && context == global_namespace)
- context = error_mark_node;
-
/* A decl in :: or ::std scope is treated specially. The former is
mangled using <unscoped-name> or <unscoped-template-name>, the
latter with a special substitution. Also, a name that is
directly in a local function scope is also mangled with
<unscoped-name> rather than a full <nested-name>. */
- if (context == global_namespace
+ if (context == NULL
+ || context == global_namespace
|| DECL_NAMESPACE_STD_P (context)
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
{
@@ -797,9 +774,6 @@ write_name (tree decl, const int ignore_local_scope)
}
else
{
- if (context == error_mark_node)
- context = global_namespace;
-
/* Handle local names, unless we asked not to (that is, invoked
under <local-name>, to handle only the part of the name under
the local scope). */
@@ -812,10 +786,10 @@ write_name (tree decl, const int ignore_local_scope)
directly in that function's scope, either decl or one of
its enclosing scopes. */
tree local_entity = decl;
- while (context != global_namespace)
+ while (context != NULL && context != global_namespace)
{
/* Make sure we're always dealing with decls. */
- if (TYPE_P (context))
+ if (context != NULL && TYPE_P (context))
context = TYPE_NAME (context);
/* Is this a function? */
if (TREE_CODE (context) == FUNCTION_DECL)
@@ -859,6 +833,7 @@ write_unscoped_name (const tree decl)
/* If not, it should be either in the global namespace, or directly
in a local function scope. */
gcc_assert (context == global_namespace
+ || context != NULL
|| TREE_CODE (context) == FUNCTION_DECL);
write_unqualified_name (decl);
@@ -930,9 +905,6 @@ write_nested_name (const tree decl)
{
/* No, just use <prefix> */
write_prefix (DECL_CONTEXT (decl));
- if (needs_fake_anon (decl))
- /* Pretend this static function is in an anonymous namespace. */
- write_source_name (get_anonymous_namespace_name ());
write_unqualified_name (decl);
}
write_char ('E');
@@ -2830,18 +2802,15 @@ mangle_decl (const tree decl)
SET_DECL_ASSEMBLER_NAME (decl, id);
}
-/* Generate the mangled representation of TYPE for the typeinfo name. */
+/* Generate the mangled representation of TYPE. */
const char *
-mangle_type_string_for_rtti (const tree type)
+mangle_type_string (const tree type)
{
const char *result;
start_mangling (type);
- /* Mangle in a fake anonymous namespace if necessary. */
- fake_anon_scope = true;
write_type (type);
- fake_anon_scope = false;
result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index ff4c497b3b0..a1a9c327fe9 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -62,14 +62,19 @@ static GTY(()) tree anonymous_namespace_name;
/* Initialize anonymous_namespace_name if necessary, and return it. */
-tree
+static tree
get_anonymous_namespace_name (void)
{
if (!anonymous_namespace_name)
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
}
return anonymous_namespace_name;
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 7cad732be3a..6d75772a1e2 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -103,7 +103,7 @@ VEC(tree,gc) *unemitted_tinfo_decls;
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
static tree ifnonnull (tree, tree);
-static tree tinfo_name (tree);
+static tree tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@@ -350,16 +350,30 @@ build_typeid (tree exp)
return exp;
}
-/* Generate the NTBS name of a type. */
+/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in front so that
+ comparisons will be done by pointer rather than string comparison. */
static tree
-tinfo_name (tree type)
+tinfo_name (tree type, bool mark_private)
{
const char *name;
+ int length;
tree name_string;
- name = mangle_type_string_for_rtti (type);
- name_string = fix_string_type (build_string (strlen (name) + 1, name));
- return name_string;
+ name = mangle_type_string (type);
+ length = strlen (name);
+
+ if (mark_private)
+ {
+ /* Inject '*' at beginning of name to force pointer comparison. */
+ char* buf = (char*) XALLOCAVEC (char, length + 2);
+ buf[0] = '*';
+ memcpy (buf + 1, name, length + 1);
+ name_string = build_string (length + 2, buf);
+ }
+ else
+ name_string = build_string (length + 1, name);
+
+ return fix_string_type (name_string);
}
/* Return a VAR_DECL for the internal ABI defined type_info object for
@@ -840,13 +854,12 @@ tinfo_base_init (tinfo_s *ti, tree target)
tree vtable_ptr;
{
- tree name_name;
+ tree name_name, name_string;
/* Generate the NTBS array variable. */
tree name_type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
NULL_TREE);
- tree name_string = tinfo_name (target);
/* Determine the name of the variable -- and remember with which
type it is associated. */
@@ -863,6 +876,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
DECL_TINFO_P (name_decl) = 1;
set_linkage_according_to_type (target, name_decl);
import_export_decl (name_decl);
+ name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a5c491b5e81..be15117ce75 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -5,6 +5,8 @@
2009-10-31 Jason Merrill <jason@redhat.com>
+ * g++.dg/rtti/typeid9.C: New.
+
PR c++/41754
* g++.dg/cpp0x/initlist25.C: New.
diff --git a/gcc/testsuite/g++.dg/rtti/typeid9.C b/gcc/testsuite/g++.dg/rtti/typeid9.C
new file mode 100644
index 00000000000..381252dc6b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid9.C
@@ -0,0 +1,21 @@
+// Test that the typeid name for a local class is properly null-terminated.
+// { dg-do run }
+
+#include <string.h>
+#include <typeinfo>
+#include <stdio.h>
+
+int f()
+{
+ struct A {}; struct B {};
+ const std::type_info &ti = typeid(A);
+ const std::type_info &ti2 = typeid(B);
+ puts (ti.name());
+ puts (ti2.name());
+ return strcmp (ti.name(), "Z1fvE1A") || strcmp (ti2.name(), "Z1fvE1B");
+}
+
+int main()
+{
+ return f();
+}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 95382a0015b..5de041c3345 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-30 Jerry Quinn <jlquinn@optonline.net>
+
+ * libsupc++/tinfo.cc (operator=(const type_info&)): Compare by
+ pointer if name begins with '*'.
+ * libsupc++/typeinfo (type_info::name()): Likewise.
+ * libsupc++/tinfo2.cc (before): Likewise.
+
2009-10-28 Johannes Singler <singler@kit.edu>
PR libstdc++/40852
diff --git a/libstdc++-v3/libsupc++/tinfo.cc b/libstdc++-v3/libsupc++/tinfo.cc
index 1ce6f8f46ab..d939a3fdab7 100644
--- a/libstdc++-v3/libsupc++/tinfo.cc
+++ b/libstdc++-v3/libsupc++/tinfo.cc
@@ -41,7 +41,8 @@ operator== (const std::type_info& arg) const
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
- return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
+ return (&arg == this)
+ || (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0));
#endif
}
diff --git a/libstdc++-v3/libsupc++/tinfo2.cc b/libstdc++-v3/libsupc++/tinfo2.cc
index 4b01037f3b9..0182c6cc0de 100644
--- a/libstdc++-v3/libsupc++/tinfo2.cc
+++ b/libstdc++-v3/libsupc++/tinfo2.cc
@@ -37,7 +37,8 @@ type_info::before (const type_info &arg) const
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
- return __builtin_strcmp (name (), arg.name ()) < 0;
+ return (name ()[0] == '*') ? name () < arg.name ()
+ : __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo
index 4c470430def..f7f9d4e2cc2 100644
--- a/libstdc++-v3/libsupc++/typeinfo
+++ b/libstdc++-v3/libsupc++/typeinfo
@@ -94,7 +94,7 @@ namespace std
/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const
- { return __name; }
+ { return __name[0] == '*' ? __name + 1 : __name; }
#if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
@@ -110,12 +110,15 @@ namespace std
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
- { return __builtin_strcmp (__name, __arg.__name) < 0; }
+ { return (__name[0] == '*' && __arg.__name[0] == '*')
+ ? __name < __arg.__name
+ : __builtin_strcmp (__name, __arg.__name) < 0; }
bool operator==(const type_info& __arg) const
{
return ((__name == __arg.__name)
- || __builtin_strcmp (__name, __arg.__name) == 0);
+ || (__name[0] != '*' &&
+ __builtin_strcmp (__name, __arg.__name) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,