This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: enable-build-with-cxx bootstrap compare broken by r149964
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
}