diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-11-02 14:43:46 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2009-11-02 14:43:46 +0000 |
commit | b36b563f1576b67a25b26bef40a77121895faa8c (patch) | |
tree | 49a070246a4bd143ab2cef548354ec86232c5522 | |
parent | 542bf15772e2e1d6d45087fa77316f096a100974 (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/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 45 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 9 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/rtti/typeid9.C | 21 | ||||
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/tinfo.cc | 3 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/tinfo2.cc | 3 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/typeinfo | 9 |
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, |