* Re: enable-build-with-cxx bootstrap compare broken by r149964 [not found] ` <4A8F1EE7.9030001@redhat.com> @ 2009-08-22 18:57 ` Jerry Quinn 0 siblings, 0 replies; 9+ messages in thread From: Jerry Quinn @ 2009-08-22 18:57 UTC (permalink / raw) To: Richard Henderson Cc: Dave Korn, Jason Merrill, gcc, Pedro Lamarão, gcc-patches On Fri, 2009-08-21 at 15:25 -0700, Richard Henderson wrote: > On 08/21/2009 02:37 PM, Jerry Quinn wrote: > > OK, I've gotten almost this far and can bootstrap (the asterisk is > > actually not the very first char and I have to figure that out). > > However, in the referenced test case, both typeinfos are apparently > > merged, thus returning the same pointer for their name strings, so > > pointer comparison still wouldn't work. > > > > Therefore, I guess I'll need to do the following: > > > >> You might also need to take steps to ensure that the typeinfo gets emitted > >> as non-COMDAT with local symbols, so that each object does indeed end up with > >> its own separate copy. > > > > Where should I look to do this? > > First thing you should do is make sure you're emitting a VAR_DECL > with the string contents, rather than a STRING_CST constant. The > later will be merged within an object file within the compiler. > > Second, make sure the VAR_DECL for the typeinfo is no DECL_ONE_ONLY. > That flag sets up COMDAT sections, which will be merged by the linker. It looks like I"ve got a working patch now. It bootstraps and has no reqressions from make check, nor from make check in the libstdc++ directory. Any thoughts? Jerry 2009-08-22 Jerry Quinn <jlquinn@optonline.net> * name-lookup.c (get_anonymous_namespace_name): Use fixed namespace "cxx_anon_ns". * mangle.c (write_nested_name): Insert '*' to mark fake anonymous namespace. (get_mangled_string_length): New function. (mangle_type_string_for_rtti): Put '*' at start of mangled namestring. * rtti.c (tinfo_base_init): Disable DECL_COMDAT for fake anonymous namespaces. 2009-08-22 Jerry Quinn <jlquinn@optonline.net> * libsupc++/tinfo.cc (typeinfo::operator==): Compare names starting with '*' by pointer. * libsupc++/tinfo2.cc (typeinfo::before): Same. * libsupc++/typeinfo (typeinfo::operator==): Same. * libsupc++/typeinfo (typeinfo::before): Same. Index: gcc/cp/rtti.c =================================================================== --- gcc/cp/rtti.c (revision 151008) +++ gcc/cp/rtti.c (working copy) @@ -862,9 +862,12 @@ DECL_TINFO_P (name_decl) = 1; set_linkage_according_to_type (target, name_decl); import_export_decl (name_decl); + /* Disable DECL_COMDAT if we have an anonymous namspace here. */ + if (TREE_STRING_POINTER (name_string)[0] == '*') + DECL_COMDAT (name_decl) = 0; DECL_INITIAL (name_decl) = name_string; mark_used (name_decl); pushdecl_top_level_and_finish (name_decl, name_string); 2009-08-21 Jakub Jelinek <jakub@redhat.com> PR c++/41131 Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 151008) +++ gcc/cp/mangle.c (working copy) @@ -935,8 +935,14 @@ /* 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 ()); + { + /* Add a * to mark fake anonymous namespaces in typeinfos as + compare-by-pointer. This * is used to put another one at the + front when done building the string. */ + write_char ('*'); + /* Pretend this static function is in an anonymous namespace. */ + write_source_name (get_anonymous_namespace_name ()); + } write_unqualified_name (decl); } write_char ('E'); @@ -2755,6 +2761,14 @@ name_base = obstack_alloc (&name_obstack, 0); } +/* Returns the length of the mangled string array. */ + +static inline int +get_mangled_string_length (void) +{ + return obstack_object_size (mangle_obstack); +} + /* Done with mangling. If WARN is true, and the name of G.entity will be mangled differently in a future version of the ABI, issue a warning. */ @@ -2851,13 +2865,20 @@ mangle_type_string_for_rtti (const tree type) { const char *result; + int result_len; start_mangling (type); /* Mangle in a fake anonymous namespace if necessary. */ fake_anon_scope = true; + /* Place marker to be removed if not dealing with a nested name. */ + write_char('*'); write_type (type); fake_anon_scope = false; + result_len = get_mangled_string_length (); result = finish_mangling (/*warn=*/false); + /* Remove the marker if not needed. */ + if (!strchr(result + 1, '*')) + result++; if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); return result; Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 151008) +++ gcc/cp/name-lookup.c (working copy) @@ -69,7 +69,7 @@ { /* 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"); + anonymous_namespace_name = get_identifier ("cxx_anon_ns"); } return anonymous_namespace_name; } Index: libstdc++-v3/libsupc++/tinfo2.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo2.cc (revision 151008) +++ libstdc++-v3/libsupc++/tinfo2.cc (working copy) @@ -37,7 +37,9 @@ #if __GXX_MERGED_TYPEINFO_NAMES return name () < arg.name (); #else - return __builtin_strcmp (name (), arg.name ()) < 0; + return (name ()[0] == '*' && arg.name()[0] == '*') + ? name () < arg.name () + : __builtin_strcmp (name (), arg.name ()) < 0; #endif } Index: libstdc++-v3/libsupc++/typeinfo =================================================================== --- libstdc++-v3/libsupc++/typeinfo (revision 151008) +++ libstdc++-v3/libsupc++/typeinfo (working copy) @@ -110,12 +110,15 @@ // 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] != '*' && __arg.__name[0] != '*' && + __builtin_strcmp (__name, __arg.__name) == 0)); } #else // On some targets we can rely on type_info's NTBS being unique, Index: libstdc++-v3/libsupc++/tinfo.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo.cc (revision 151008) +++ libstdc++-v3/libsupc++/tinfo.cc (working copy) @@ -41,7 +41,9 @@ #if __GXX_MERGED_TYPEINFO_NAMES return name () == arg.name (); #else - return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0); + return (&arg == this) + || (name ()[0] != '*' && arg.name ()[0] != '*' + && (__builtin_strcmp (name (), arg.name ()) == 0)); #endif } ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <4A960A78.8040704@redhat.com>]
[parent not found: <1251694626.7629.2.camel@cerberus.qb5.org>]
[parent not found: <4AAE6745.3070706@redhat.com>]
[parent not found: <4AB7B28E.7030501@redhat.com>]
[parent not found: <1253617474.4274.2795.camel@cerberus.qb5.org>]
[parent not found: <4AB8D3D1.8010704@redhat.com>]
[parent not found: <1253712164.4274.2800.camel@cerberus.qb5.org>]
[parent not found: <4ABA391C.2050903@redhat.com>]
* Re: enable-build-with-cxx bootstrap compare broken by r149964 [not found] ` <4ABA391C.2050903@redhat.com> @ 2009-10-24 5:28 ` Jerry Quinn 2009-10-26 11:15 ` Jakub Jelinek 0 siblings, 1 reply; 9+ messages in thread From: Jerry Quinn @ 2009-10-24 5:28 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC, gcc-patches On Wed, 2009-09-23 at 11:05 -0400, Jason Merrill wrote: > On 09/23/2009 09:22 AM, Jerry Quinn wrote: > > I'm not really sure how everything fits together here. Am I missing > > something obvious? > > I notice that you're missing the fix_string_type that tinfo_name does. > But I'd rather not duplicate the code that creates the STRING_CST; > better to delay the call to tinfo_name and add the * there. > > Jason Hi, Jason, Sorry, it took me a while to get back to this. Here's the latest patch I have updated to today's tree. It fixes bootstrap, but there are a number of testsuite failures. They all appear to plugin test failures similar to below. I don't know if this is related to my patch or is caused by some other issue when building with --enable-build-with-cxx. PR 40923 is about the bootstrap problem, and I've attached the patch there as well. Jerry Executing on build: gcc -g -O2 /home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/g ++.dg/plugin/dumb_plugin.c -I. -I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite -I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../gcc -I/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g++/../../../gcc -I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../include -I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../libcpp/include -DIN_GCC -fPIC -shared -o dumb_plugin.so (timeout = 300) set_ld_library_path_env_vars: ld_library_path=.:/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/./libstdc++-v3/src/.libs:/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/./libstdc++-v3/src/.libs:/home/jlquinn/gcc/dev/build/trunk-cxx/gcc:/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/32 Executing on host: /home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g ++/../../g++ -B/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g ++/../../ /home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/g ++.dg/plugin/dumb-plugin-test-1.C -nostdinc++ -I/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/libstdc ++-v3/include/x86_64-unknown-linux-gnu -I/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/libstdc ++-v3/include -I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/libsupc++ -I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/include/backward -I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/testsuite/util -fmessage-length=0 -fplugin=./dumb_plugin.so -O -fplugin-arg-dumb_plugin-ref-pass-name=ccp -fplugin-arg-dumb_plugin-ref-pass-instance-num=1 -S -o dumb-plugin-test-1.s (timeout = 300) cc1plus: error: Cannot load plugin ./dumb_plugin.so ./dumb_plugin.so: undefined symbol: tree_check_failed compiler exited with status 1 output is: cc1plus: error: Cannot load plugin ./dumb_plugin.so ./dumb_plugin.so: undefined symbol: tree_check_failed FAIL: g++.dg/plugin/dumb-plugin-test-1.C -fplugin=./dumb_plugin.so (test for warnings, line 10) Patch below: Index: gcc/cp/rtti.c =================================================================== --- gcc/cp/rtti.c (revision 153489) +++ gcc/cp/rtti.c (working copy) @@ -102,7 +102,7 @@ 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); @@ -349,16 +349,31 @@ 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*) XNEWVEC (char, length + 1); + buf[0] = '*'; + memcpy (buf + 1, name, length); + name_string = build_string (length + 1, buf); + XDELETEVEC (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 @@ -839,13 +854,13 @@ 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); + // tree name_string = tinfo_name (target); /* Determine the name of the variable -- and remember with which type it is associated. */ @@ -862,6 +877,7 @@ 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); Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 153489) +++ gcc/cp/mangle.c (working copy) @@ -105,10 +105,6 @@ 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; @@ -734,20 +730,6 @@ } } -/* 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); -} - /* Lambdas can have a bit more context for mangling, specifically VAR_DECL or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */ @@ -791,18 +773,13 @@ context = decl_mangling_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)) { @@ -820,9 +797,6 @@ } 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). */ @@ -835,10 +809,10 @@ 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 @@ -883,6 +857,7 @@ /* 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); @@ -954,9 +929,6 @@ { /* 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'); @@ -2921,10 +2893,6 @@ name_base = obstack_alloc (&name_obstack, 0); } -/* Done with mangling. If WARN is true, and the name of G.entity will - be mangled differently in a future version of the ABI, issue a - warning. */ - static void finish_mangling_internal (const bool warn) { @@ -3011,18 +2979,15 @@ 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); Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 153489) +++ gcc/cp/cp-tree.h (working copy) @@ -4507,7 +4507,6 @@ extern tree perform_qualification_conversions (tree, tree); /* in name-lookup.c */ -extern tree get_anonymous_namespace_name (void); extern tree pushdecl (tree); extern tree pushdecl_maybe_friend (tree, bool); extern void maybe_push_cleanup_level (tree); @@ -5288,7 +5287,7 @@ /* 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); Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 153489) +++ gcc/cp/name-lookup.c (working copy) @@ -69,7 +69,12 @@ { /* 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; } Index: libstdc++-v3/libsupc++/tinfo2.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo2.cc (working copy) @@ -37,7 +37,9 @@ #if __GXX_MERGED_TYPEINFO_NAMES return name () < arg.name (); #else - return __builtin_strcmp (name (), arg.name ()) < 0; + return (name ()[0] == '*' && arg.name()[0] == '*') + ? name () < arg.name () + : __builtin_strcmp (name (), arg.name ()) < 0; #endif } Index: libstdc++-v3/libsupc++/typeinfo =================================================================== --- libstdc++-v3/libsupc++/typeinfo (revision 153489) +++ libstdc++-v3/libsupc++/typeinfo (working copy) @@ -94,7 +94,7 @@ /** 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 @@ // 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] != '*' && __arg.__name[0] != '*' && + __builtin_strcmp (__name, __arg.__name) == 0)); } #else // On some targets we can rely on type_info's NTBS being unique, Index: libstdc++-v3/libsupc++/tinfo.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo.cc (working copy) @@ -41,7 +41,9 @@ #if __GXX_MERGED_TYPEINFO_NAMES return name () == arg.name (); #else - return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0); + return (&arg == this) + || (name ()[0] != '*' && arg.name ()[0] != '*' + && (__builtin_strcmp (name (), arg.name ()) == 0)); #endif } ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-24 5:28 ` Jerry Quinn @ 2009-10-26 11:15 ` Jakub Jelinek 2009-10-26 14:42 ` Jason Merrill 0 siblings, 1 reply; 9+ messages in thread From: Jakub Jelinek @ 2009-10-26 11:15 UTC (permalink / raw) To: Jerry Quinn; +Cc: Jason Merrill, GCC, gcc-patches Hi! Just some random comments: On Sat, Oct 24, 2009 at 12:10:52AM -0400, Jerry Quinn wrote: > + if (mark_private) > + { > + /* Inject '*' at beginning of name to force pointer comparison. > */ > + char* buf = (char*) XNEWVEC (char, length + 1); > + buf[0] = '*'; > + memcpy (buf + 1, name, length); > + name_string = build_string (length + 1, buf); > + XDELETEVEC (buf); You could as well use XALLOCAVEC (char, length + 1) and remove XDELETEVEC. No need to cast the result of XNEWVEC or XALLOCAVEC to char *. And, the formatting is wrong, space goes after char, no space between * and buf. > /* 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); > + // tree name_string = tinfo_name (target); This should be removed, rather than commented out. > @@ -2921,10 +2893,6 @@ > name_base = obstack_alloc (&name_obstack, 0); > } > > -/* Done with mangling. If WARN is true, and the name of G.entity will > - be mangled differently in a future version of the ABI, issue a > - warning. */ > - > static void > finish_mangling_internal (const bool warn) > { Why are you removing the comment? > @@ -3011,18 +2979,15 @@ > 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) Why this change? > bool operator==(const type_info& __arg) const > { > return ((__name == __arg.__name) > - || __builtin_strcmp (__name, __arg.__name) == 0); > + || (__name[0] != '*' && __arg.__name[0] != '*' && > + __builtin_strcmp (__name, __arg.__name) == 0)); I see no point in both tests for * here, just __name[0] != '*' should be enough (or __arg.__name[0] != '*'). If one string starts with * and the other doesn't, strcmp will return non-0. > --- libstdc++-v3/libsupc++/tinfo.cc (revision 153489) > +++ libstdc++-v3/libsupc++/tinfo.cc (working copy) > @@ -41,7 +41,9 @@ > #if __GXX_MERGED_TYPEINFO_NAMES > return name () == arg.name (); > #else > - return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == > 0); > + return (&arg == this) > + || (name ()[0] != '*' && arg.name ()[0] != '*' > + && (__builtin_strcmp (name (), arg.name ()) == 0)); > #endif > } Likewise. Jakub ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-26 11:15 ` Jakub Jelinek @ 2009-10-26 14:42 ` Jason Merrill 2009-10-28 12:49 ` Jerry Quinn 0 siblings, 1 reply; 9+ messages in thread From: Jason Merrill @ 2009-10-26 14:42 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jerry Quinn, GCC, gcc-patches On 10/26/2009 07:14 AM, Jakub Jelinek wrote: >> -/* 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) > > Why this change? This change is part of reverting my earlier fake namespace patch. I agree with Jakub's other comments, though. Jason ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-26 14:42 ` Jason Merrill @ 2009-10-28 12:49 ` Jerry Quinn 2009-10-28 15:52 ` Jason Merrill 0 siblings, 1 reply; 9+ messages in thread From: Jerry Quinn @ 2009-10-28 12:49 UTC (permalink / raw) To: Jason Merrill; +Cc: Jakub Jelinek, GCC, gcc-patches On Mon, 2009-10-26 at 09:53 -0400, Jason Merrill wrote: > On 10/26/2009 07:14 AM, Jakub Jelinek wrote: > >> -/* 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) > > > > Why this change? > > This change is part of reverting my earlier fake namespace patch. > > I agree with Jakub's other comments, though. > > Jason Here's the updated patch. 2009-10-28 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-28 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. Index: gcc/cp/rtti.c =================================================================== --- gcc/cp/rtti.c (revision 153489) +++ gcc/cp/rtti.c (working copy) @@ -102,7 +102,7 @@ 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); @@ -349,16 +349,30 @@ 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 + 1); + buf[0] = '*'; + memcpy (buf + 1, name, length); + name_string = build_string (length + 1, 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 @@ -839,13 +853,12 @@ 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. */ @@ -862,6 +875,7 @@ 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); Index: gcc/cp/ChangeLog =================================================================== --- gcc/cp/ChangeLog (revision 153489) +++ gcc/cp/ChangeLog (working copy) @@ -1,3 +1,15 @@ +2009-10-28 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-21 Jakub Jelinek <jakub@redhat.com> * mangle.c (finish_mangling_get_identifier): Use Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 153489) +++ gcc/cp/mangle.c (working copy) @@ -105,10 +105,6 @@ 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; @@ -734,20 +730,6 @@ } } -/* 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); -} - /* Lambdas can have a bit more context for mangling, specifically VAR_DECL or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */ @@ -791,18 +773,13 @@ context = decl_mangling_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)) { @@ -820,9 +797,6 @@ } 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). */ @@ -835,10 +809,10 @@ 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 @@ -883,6 +857,7 @@ /* 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); @@ -954,9 +929,6 @@ { /* 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'); @@ -3011,18 +2983,15 @@ 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); Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 153489) +++ gcc/cp/cp-tree.h (working copy) @@ -4507,7 +4507,6 @@ extern tree perform_qualification_conversions (tree, tree); /* in name-lookup.c */ -extern tree get_anonymous_namespace_name (void); extern tree pushdecl (tree); extern tree pushdecl_maybe_friend (tree, bool); extern void maybe_push_cleanup_level (tree); @@ -5288,7 +5287,7 @@ /* 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); Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 153489) +++ gcc/cp/name-lookup.c (working copy) @@ -62,14 +62,19 @@ /* 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; } Index: libstdc++-v3/libsupc++/tinfo2.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo2.cc (working copy) @@ -37,7 +37,8 @@ #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 } Index: libstdc++-v3/libsupc++/typeinfo =================================================================== --- libstdc++-v3/libsupc++/typeinfo (revision 153489) +++ libstdc++-v3/libsupc++/typeinfo (working copy) @@ -94,7 +94,7 @@ /** 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 @@ // 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, Index: libstdc++-v3/libsupc++/tinfo.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo.cc (working copy) @@ -41,7 +41,8 @@ #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 } Index: libstdc++-v3/ChangeLog =================================================================== --- libstdc++-v3/ChangeLog (revision 153489) +++ libstdc++-v3/ChangeLog (working copy) @@ -1,3 +1,10 @@ +2009-10-28 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. + 009-10-20 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/41773 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-28 12:49 ` Jerry Quinn @ 2009-10-28 15:52 ` Jason Merrill 2009-10-29 5:35 ` Jerry Quinn 0 siblings, 1 reply; 9+ messages in thread From: Jason Merrill @ 2009-10-28 15:52 UTC (permalink / raw) To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches On 10/28/2009 07:29 AM, Jerry Quinn wrote: > + length = strlen (name); > + if (mark_private) > + name_string = build_string (length + 1, buf); > + else > + name_string = build_string (length + 1, name); These two calls shouldn't be using the same length. I think the +1 in the old code was unnecessary, so you can just remove it from the second call. Jason ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-28 15:52 ` Jason Merrill @ 2009-10-29 5:35 ` Jerry Quinn 2009-10-29 6:45 ` Jason Merrill 0 siblings, 1 reply; 9+ messages in thread From: Jerry Quinn @ 2009-10-29 5:35 UTC (permalink / raw) To: Jason Merrill; +Cc: Jakub Jelinek, GCC, gcc-patches On Wed, 2009-10-28 at 11:35 -0400, Jason Merrill wrote: > On 10/28/2009 07:29 AM, Jerry Quinn wrote: > > + length = strlen (name); > > + if (mark_private) > > + name_string = build_string (length + 1, buf); > > + else > > + name_string = build_string (length + 1, name); > > These two calls shouldn't be using the same length. I think the +1 in > the old code was unnecessary, so you can just remove it from the second > call. And here is the latest patch. Index: gcc/cp/rtti.c =================================================================== --- gcc/cp/rtti.c (revision 153489) +++ gcc/cp/rtti.c (working copy) @@ -102,7 +102,7 @@ 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); @@ -349,16 +349,30 @@ 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 + 1); + buf[0] = '*'; + memcpy (buf + 1, name, length); + name_string = build_string (length + 1, buf); + } + else + name_string = build_string (length, name); + + return fix_string_type (name_string); } /* Return a VAR_DECL for the internal ABI defined type_info object for @@ -839,13 +853,12 @@ 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. */ @@ -862,6 +875,7 @@ 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); Index: gcc/cp/ChangeLog =================================================================== --- gcc/cp/ChangeLog (revision 153489) +++ gcc/cp/ChangeLog (working copy) @@ -1,3 +1,15 @@ +2009-10-28 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-21 Jakub Jelinek <jakub@redhat.com> * mangle.c (finish_mangling_get_identifier): Use Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 153489) +++ gcc/cp/mangle.c (working copy) @@ -105,10 +105,6 @@ 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; @@ -734,20 +730,6 @@ } } -/* 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); -} - /* Lambdas can have a bit more context for mangling, specifically VAR_DECL or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */ @@ -791,18 +773,13 @@ context = decl_mangling_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)) { @@ -820,9 +797,6 @@ } 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). */ @@ -835,10 +809,10 @@ 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 @@ -883,6 +857,7 @@ /* 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); @@ -954,9 +929,6 @@ { /* 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'); @@ -3011,18 +2983,15 @@ 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); Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 153489) +++ gcc/cp/cp-tree.h (working copy) @@ -4507,7 +4507,6 @@ extern tree perform_qualification_conversions (tree, tree); /* in name-lookup.c */ -extern tree get_anonymous_namespace_name (void); extern tree pushdecl (tree); extern tree pushdecl_maybe_friend (tree, bool); extern void maybe_push_cleanup_level (tree); @@ -5288,7 +5287,7 @@ /* 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); Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 153489) +++ gcc/cp/name-lookup.c (working copy) @@ -62,14 +62,19 @@ /* 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; } Index: libstdc++-v3/libsupc++/tinfo2.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo2.cc (working copy) @@ -37,7 +37,8 @@ #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 } Index: libstdc++-v3/libsupc++/typeinfo =================================================================== --- libstdc++-v3/libsupc++/typeinfo (revision 153489) +++ libstdc++-v3/libsupc++/typeinfo (working copy) @@ -94,7 +94,7 @@ /** 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 @@ // 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, Index: libstdc++-v3/libsupc++/tinfo.cc =================================================================== --- libstdc++-v3/libsupc++/tinfo.cc (revision 153489) +++ libstdc++-v3/libsupc++/tinfo.cc (working copy) @@ -41,7 +41,8 @@ #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 } Index: libstdc++-v3/ChangeLog =================================================================== --- libstdc++-v3/ChangeLog (revision 153489) +++ libstdc++-v3/ChangeLog (working copy) @@ -1,3 +1,10 @@ +2009-10-28 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. + 009-10-20 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/41773 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-29 5:35 ` Jerry Quinn @ 2009-10-29 6:45 ` Jason Merrill 2009-11-01 5:02 ` Jason Merrill 0 siblings, 1 reply; 9+ messages in thread From: Jason Merrill @ 2009-10-29 6:45 UTC (permalink / raw) To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches On 10/29/2009 01:06 AM, Jerry Quinn wrote: > And here is the latest patch. This one is OK, thanks. Jason ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964 2009-10-29 6:45 ` Jason Merrill @ 2009-11-01 5:02 ` Jason Merrill 0 siblings, 0 replies; 9+ messages in thread From: Jason Merrill @ 2009-11-01 5:02 UTC (permalink / raw) To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches [-- Attachment #1: Type: text/plain, Size: 54 bytes --] Here's the fix I'm checking in for the * path. Jason [-- Attachment #2: tinfo-null.patch --] [-- Type: text/x-patch, Size: 1506 bytes --] commit 16463ef55164d4668d6f1eeb150974452e1dbe58 Author: Jason Merrill <jason@redhat.com> Date: Sat Oct 31 18:10:17 2009 -0400 * rtti.c (tinfo_name): Fix lengths for private case. diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 2926f97..c7af74a 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -364,10 +364,10 @@ tinfo_name (tree type, bool mark_private) if (mark_private) { /* Inject '*' at beginning of name to force pointer comparison. */ - char* buf = (char*) XALLOCAVEC (char, length + 1); + char* buf = (char*) XALLOCAVEC (char, length + 2); buf[0] = '*'; - memcpy (buf + 1, name, length); - name_string = build_string (length + 1, buf); + memcpy (buf + 1, name, length + 1); + name_string = build_string (length + 2, buf); } else name_string = build_string (length + 1, name); diff --git a/gcc/testsuite/g++.dg/rtti/typeid9.C b/gcc/testsuite/g++.dg/rtti/typeid9.C new file mode 100644 index 0000000..381252d --- /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(); +} ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-11-01 5:02 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <1250345548.19163.155.camel@cerberus.qb5.org> [not found] ` <4A89BA99.1000900@redhat.com> [not found] ` <1250563251.4312.6.camel@cerberus.qb5.org> [not found] ` <4A8ACC37.8020200@redhat.com> [not found] ` <1250743680.4312.38.camel@cerberus.qb5.org> [not found] ` <4A8D218D.20209@gmail.com> [not found] ` <1250771594.4312.40.camel@cerberus.qb5.org> [not found] ` <4A8D4A1A.4080902@gmail.com> [not found] ` <1250775261.4312.48.camel@cerberus.qb5.org> [not found] ` <4A8D5C3B.7010604@gmail.com> [not found] ` <1250890624.4312.54.camel@cerberus.qb5.org> [not found] ` <4A8F1EE7.9030001@redhat.com> 2009-08-22 18:57 ` enable-build-with-cxx bootstrap compare broken by r149964 Jerry Quinn [not found] ` <4A960A78.8040704@redhat.com> [not found] ` <1251694626.7629.2.camel@cerberus.qb5.org> [not found] ` <4AAE6745.3070706@redhat.com> [not found] ` <4AB7B28E.7030501@redhat.com> [not found] ` <1253617474.4274.2795.camel@cerberus.qb5.org> [not found] ` <4AB8D3D1.8010704@redhat.com> [not found] ` <1253712164.4274.2800.camel@cerberus.qb5.org> [not found] ` <4ABA391C.2050903@redhat.com> 2009-10-24 5:28 ` Jerry Quinn 2009-10-26 11:15 ` Jakub Jelinek 2009-10-26 14:42 ` Jason Merrill 2009-10-28 12:49 ` Jerry Quinn 2009-10-28 15:52 ` Jason Merrill 2009-10-29 5:35 ` Jerry Quinn 2009-10-29 6:45 ` Jason Merrill 2009-11-01 5:02 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).