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]

Fix type_info comparison for ARM EABI


On ARM EABI,

FAIL: g++.dg/abi/local1.C execution test

appears because the out-of-line type_info comparison uses strcmp.  The
ARM EABI requires old-of-line type_info comparison for the reason
explained in bpabi.h:

/* The BPABI requires that we always use an out-of-line implementation
   of RTTI comparison, even if the target supports weak symbols,
   because the same object file might be used on a target that does
   not support merging symbols across DLL boundaries. ... */

but this does not specify the particular algorithm used by the
out-of-line implementation.  On targets that do merge symbols
properly, the out-of-line implementation can use pointer comparison.

Thus, __GXX_MERGED_TYPEINFO_NAMES means two different things (both
whether the comparison is inline and what algorithm it uses), and they
should be separated into two different macros, which this patch does.
Tested arm-none-eabi.  OK to commit?

gcc:
2006-11-01  Joseph Myers  <joseph@codesourcery.com>

	* config/arm/bpapi.h (TARGET_BPABI_CPP_BUILTINS): Define
	__GXX_TYPEINFO_EQUALITY_INLINE but not
	__GXX_MERGED_TYPEINFO_NAMES.
	* config/arm/symbian.h (TARGET_OS_CPP_BUILTINS): Define
	__GXX_MERGED_TYPEINFO_NAMES.
	* config/i386/cygming.h (TARGET_OS_CPP_BUILTINS): Define
	__GXX_TYPEINFO_EQUALITY_INLINE.

libstdc++-v3:
2006-11-01  Joseph Myers  <joseph@codesourcery.com>

	* libsupc++/typeinfo (__GXX_TYPEINFO_EQUALITY_INLINE): Define.
	Use instead of __GXX_MERGED_TYPEINFO_NAMES to condition inline
	definitions.
	* libsupc++/tinfo.cc (operator==): Condition on
	__GXX_TYPEINFO_EQUALITY_INLINE; check __GXX_MERGED_TYPEINFO_NAMES
	to determine algorithm.
	* libsupc++/tinfo2.cc (type_info::before): Likewise.

Index: gcc/config/i386/cygming.h
===================================================================
--- gcc/config/i386/cygming.h	(revision 118229)
+++ gcc/config/i386/cygming.h	(working copy)
@@ -70,6 +70,7 @@
 	/* Even though linkonce works with static libs, this is needed 	\
 	    to compare typeinfo symbols across dll boundaries.  */	\
 	builtin_define ("__GXX_MERGED_TYPEINFO_NAMES=0");		\
+	builtin_define ("__GXX_TYPEINFO_EQUALITY_INLINE=0");		\
 	MAYBE_UWIN_CPP_BUILTINS ();					\
 	EXTRA_OS_CPP_BUILTINS ();					\
   }									\
Index: gcc/config/arm/symbian.h
===================================================================
--- gcc/config/arm/symbian.h	(revision 118229)
+++ gcc/config/arm/symbian.h	(working copy)
@@ -79,13 +79,16 @@
 
 /* Define the __symbian__ macro.  */
 #undef TARGET_OS_CPP_BUILTINS
-#define TARGET_OS_CPP_BUILTINS()		\
-  do						\
-    {						\
-      /* Include the default BPABI stuff.  */	\
-      TARGET_BPABI_CPP_BUILTINS ();		\
-      builtin_define ("__symbian__");		\
-    }						\
+#define TARGET_OS_CPP_BUILTINS()				\
+  do								\
+    {								\
+      /* Include the default BPABI stuff.  */			\
+      TARGET_BPABI_CPP_BUILTINS ();				\
+      /* Symbian OS does not support merging symbols across DLL	\
+	 boundaries.  */					\
+      builtin_define ("__GXX_MERGED_TYPEINFO_NAMES=0");		\
+      builtin_define ("__symbian__");				\
+    }								\
   while (false)
 
 /* On SymbianOS, these sections are not writable, so we use "a",
Index: gcc/config/arm/bpabi.h
===================================================================
--- gcc/config/arm/bpabi.h	(revision 118229)
+++ gcc/config/arm/bpabi.h	(working copy)
@@ -102,7 +102,7 @@
 #define TARGET_BPABI_CPP_BUILTINS()			\
   do							\
     {							\
-      builtin_define ("__GXX_MERGED_TYPEINFO_NAMES=0");	\
+      builtin_define ("__GXX_TYPEINFO_EQUALITY_INLINE=0");	\
     }							\
   while (false)
 
Index: libstdc++-v3/libsupc++/tinfo2.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo2.cc	(revision 118229)
+++ libstdc++-v3/libsupc++/tinfo2.cc	(working copy)
@@ -38,12 +38,16 @@
 
 using std::type_info;
 
-#if !__GXX_MERGED_TYPEINFO_NAMES
+#if !__GXX_TYPEINFO_EQUALITY_INLINE
 
 bool
 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;
+#endif
 }
 
 #endif
Index: libstdc++-v3/libsupc++/typeinfo
===================================================================
--- libstdc++-v3/libsupc++/typeinfo	(revision 118229)
+++ libstdc++-v3/libsupc++/typeinfo	(working copy)
@@ -56,6 +56,15 @@
   #endif
 #endif
 
+// By default follow the same rules as for __GXX_MERGED_TYPEINFO_NAMES.
+#ifndef __GXX_TYPEINFO_EQUALITY_INLINE
+  #if !__GXX_WEAK__
+    #define __GXX_TYPEINFO_EQUALITY_INLINE 0
+  #else
+    #define __GXX_TYPEINFO_EQUALITY_INLINE 1
+  #endif
+#endif
+
 namespace std 
 {
   /**
@@ -91,13 +100,16 @@
     const char* name() const
     { return __name; }
 
-#if !__GXX_MERGED_TYPEINFO_NAMES
+#if !__GXX_TYPEINFO_EQUALITY_INLINE
     bool before(const type_info& __arg) const;
     // In old abi, or when weak symbols are not supported, there can
     // be multiple instances of a type_info object for one
     // type. Uniqueness must use the _name value, not object address.
     bool operator==(const type_info& __arg) const;
 #else
+  #if !__GXX_MERGED_TYPEINFO_NAMES
+    #error "Inline implementation of type_info comparision requires merging of type_info objects"
+  #endif
     /** Returns true if @c *this precedes @c __arg in the implementation's
      *  collation order.  */
     // In new abi we can rely on type_info's NTBS being unique,
Index: libstdc++-v3/libsupc++/tinfo.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo.cc	(revision 118229)
+++ libstdc++-v3/libsupc++/tinfo.cc	(working copy)
@@ -44,13 +44,17 @@
 std::bad_cast::~bad_cast() throw() { }
 std::bad_typeid::~bad_typeid() throw() { }
 
-#if !__GXX_MERGED_TYPEINFO_NAMES
+#if !__GXX_TYPEINFO_EQUALITY_INLINE
 
 // We can't rely on common symbols being shared between shared objects.
 bool std::type_info::
 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);
+#endif
 }
 
 #endif

-- 
Joseph S. Myers
joseph@codesourcery.com


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