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]

[C++ PATCH] Mangle overloaded operators even in "C" linkage


Hi!

The testcase below which Jason said should be compilable does not compile,
since no mangling happens and thus operator!= function names are written
into assembly file and assembler obviously chokes on it.
This patch tries to fix it by partly mangling such names (by partly I mean
it will not put in the arguments, so for operator!= becomes _Zne (resp. __ne
in old ABI).
I think DECL_OVERLOADED_OPERATOR_P != ERROR_MARK is the only case which
needs such handling, because the rest of weird names either get "C++"
linkage quietly when ctype != NULL_TREE in grokfndecl or get it overwritten
later because of overloading (such as with 
extern "C" {
inline void *operator new (size_t s)
{
  return p;
}
};
).
Ok to commit if bootstrap I just started succeeds and no regressions come
up?

2001-01-24  Jakub Jelinek  <jakub@redhat.com>

	* mangle.c (write_mangled_name, write_encoding): Mangle overloaded
	operators even in "C" linkage.
	* method.c (set_mangled_name_for_decl): Likewise.
	* decl.c (grokfndecl): Call set_mangled_name_for_decl even for
	overloaded operators in "C" linkage.

	* g++.old-deja/g++.other/mangle2.C: New test.

--- gcc/cp/mangle.c.jj	Fri Jan 12 11:35:46 2001
+++ gcc/cp/mangle.c	Wed Jan 24 22:42:53 2001
@@ -602,10 +602,14 @@ write_mangled_name (decl)
 {
   MANGLE_TRACE_TREE ("mangled-name", decl);
 
-  if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
+  if (DECL_LANG_SPECIFIC (decl)
+      && DECL_EXTERN_C_FUNCTION_P (decl)
+      && ! DECL_OVERLOADED_OPERATOR_P (decl))
     /* The standard notes:
          "The <encoding> of an extern "C" function is treated like
-	 global-scope data, i.e. as its <source-name> without a type."  */
+	 global-scope data, i.e. as its <source-name> without a type."
+       We cannot write overloaded operators that way though,
+       because it contains characters invalid in assembler.  */
     write_source_name (DECL_NAME (decl));
   else
     /* C++ name; needs to be mangled.  */
@@ -626,7 +630,12 @@ write_encoding (decl)
 
   if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
     {
-      write_source_name (DECL_NAME (decl));
+      /* For overloaded operators write just the mangled name
+	 without arguments.  */
+      if (DECL_OVERLOADED_OPERATOR_P (decl))
+	write_name (decl, /*ignore_local_scope=*/0);
+      else
+	write_source_name (DECL_NAME (decl));
       return;
     }
 
--- gcc/cp/method.c.jj	Fri Jan 12 11:35:46 2001
+++ gcc/cp/method.c	Wed Jan 24 22:43:37 2001
@@ -1763,6 +1763,24 @@ set_mangled_name_for_decl (decl)
       return;
     }
 
+  if (DECL_EXTERN_C_P (decl))
+    {
+      /* In extern "C" we have to mangle at least overloaded operators,
+	 because they contain characters invalid in assembler.  */
+      enum tree_code code = DECL_OVERLOADED_OPERATOR_P (decl);
+      const char *name;
+
+      if (code)
+	{
+	  if (DECL_ASSIGNMENT_OPERATOR_P (decl))
+	    name = assignment_operator_name_info[(int) code].mangled_name;
+	  else
+	    name = operator_name_info[(int) code].mangled_name;
+	  DECL_ASSEMBLER_NAME (decl) = get_identifier (name);
+	  return;
+	}
+    }
+
   parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
 
   if (DECL_STATIC_FUNCTION_P (decl))
--- gcc/cp/decl.c.jj	Tue Jan 23 14:47:51 2001
+++ gcc/cp/decl.c	Wed Jan 24 22:37:25 2001
@@ -8846,7 +8846,7 @@ grokfndecl (ctype, type, declarator, ori
 
   /* Plain overloading: will not be grok'd by grokclassfn.  */
   if (! ctype && ! processing_template_decl
-      && !DECL_EXTERN_C_P (decl)
+      && (! DECL_EXTERN_C_P (decl) || DECL_OVERLOADED_OPERATOR_P (decl))
       && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
     set_mangled_name_for_decl (decl);
 
--- gcc/testsuite/g++.old-deja/g++.other/mangle2.C.jj	Wed Jan 24 22:51:38 2001
+++ gcc/testsuite/g++.old-deja/g++.other/mangle2.C	Wed Jan 24 22:50:38 2001
@@ -0,0 +1,24 @@
+// Test for overloaded operators in "C" linkage
+// Build don't link:
+
+extern "C" {
+typedef struct b
+{
+  int a;
+} c;
+
+extern const c z;
+
+inline bool operator!=(const c& x, const c& y)
+{
+  return x.a != y.a;
+}
+};
+
+void foo();
+
+void bar(c x)
+{
+  if (x != z)
+    foo();
+}

	Jakub

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