This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
 }
 





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]