This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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 PR 31775, name mangling conflict between static and extern


There's discussion of the problem in <http://gcc.gnu.org/PR31775>.
Basically, mangled names of objects and functions with internal
linkage need to be different to mangled names of those with external
linkage, because it's possible to refer to both within the same
translation unit.

I'm using the same mangling I'm developing for IMA, although slightly
simplified.  There are many other possible manglings; but I've already
had that bikeshed discussion and I think this one will work as well as
any.

Mark, Ian, you had comments about a previous version of the libiberty
part of this patch.  Mark, do you still object?

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-cp-5173149.patch======================
Index: gcc/cp/ChangeLog
2007-05-01  Geoffrey Keating  <geoffk@apple.com>

	PR 31775
	* mangle.c (write_mangled_name): Mangle static variable names.
	(write_unqualified_name): Use local-source-name for
	namespace-scope static variables.

Index: gcc/testsuite/ChangeLog
2007-05-02  Geoffrey Keating  <geoffk@apple.com>

	PR 31775
	* g++.dg/other/nested-extern.h: New.
	* g++.dg/other/nested-extern-1.C: New.
	* g++.dg/other/nested-extern-2.C: New.

Index: libiberty/ChangeLog
2007-05-01  Geoffrey Keating  <geoffk@apple.com>

	* cp-demangle.c (d_name): Detect local-source-name.
	(d_prefix): Likewise.
	(d_unqualified_name): Implement local-source-name.

Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c	(revision 124287)
+++ gcc/cp/mangle.c	(working copy)
@@ -688,7 +688,8 @@
 	}
     }
   else if (TREE_CODE (decl) == VAR_DECL
-	   /* The names of global variables aren't mangled.  */
+	   && TREE_PUBLIC (decl)
+	   /* The names of non-static global variables aren't mangled.  */
 	   && (CP_DECL_CONTEXT (decl) == global_namespace
 	       /* And neither are `extern "C"' variables.  */
 	       || DECL_EXTERN_C_P (decl)))
@@ -1086,8 +1087,11 @@
 
     <unqualified-name>  ::= <operator-name>
 			::= <special-name>
-			::= <source-name>  */
+			::= <source-name>
+			::= <local-source-name> 
 
+    <local-source-name>	::= L <source-name> <discriminator> */
+
 static void
 write_unqualified_name (const tree decl)
 {
@@ -1126,6 +1130,16 @@
 
       write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
     }
+  else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
+	   && DECL_NAMESPACE_SCOPE_P (decl)
+	   && TREE_PUBLIC (CP_DECL_CONTEXT (decl)))
+    {
+      MANGLE_TRACE_TREE ("local-source-name", decl);
+      write_char ('L');
+      write_source_name (DECL_NAME (decl));
+      /* The default discriminator is 1, and that's all we ever use,
+	 so there's no code to output one here.  */
+    }
   else
     write_source_name (DECL_NAME (decl));
 }
Index: gcc/testsuite/g++.dg/other/nested-extern-1.C
===================================================================
--- gcc/testsuite/g++.dg/other/nested-extern-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/other/nested-extern-1.C	(revision 0)
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-x c++ ${srcdir}/g++.dg/other/nested-extern.h" } */
+/* PR 31775 */
+extern "C" void abort();
+extern int *p;
+int main()
+{ 
+  extern int i;
+  i = 1;
+  *p = 2;
+  if (i == 2)
+    abort ();
+  return 0;
+}
+
+static int i;
+int *p = &i;
Index: gcc/testsuite/g++.dg/other/nested-extern.h
===================================================================
--- gcc/testsuite/g++.dg/other/nested-extern.h	(revision 0)
+++ gcc/testsuite/g++.dg/other/nested-extern.h	(revision 0)
@@ -0,0 +1 @@
+int i;
Index: gcc/testsuite/g++.dg/other/nested-extern-2.C
===================================================================
--- gcc/testsuite/g++.dg/other/nested-extern-2.C	(revision 0)
+++ gcc/testsuite/g++.dg/other/nested-extern-2.C	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-x c++ ${srcdir}/g++.dg/other/nested-extern.h" } */
+/* PR 31775 */
+extern "C" void abort();
+static int i;
+int *p = &i;
+int main()
+{ 
+  int i;
+  { 
+    extern int i;
+    i = 1;
+    *p = 2;
+    if (i == 2)
+      abort ();
+  }
+  return 0;
+}
Index: libiberty/testsuite/demangle-expected
===================================================================
--- libiberty/testsuite/demangle-expected	(revision 124287)
+++ libiberty/testsuite/demangle-expected	(working copy)
@@ -3842,3 +3842,19 @@
 --format=gnu-v3
 _Z1aMark
 _Z1aMark
+# <local-source-name> test 1
+--format=gnu-v3
+_ZL3foo_2
+foo
+# <local-source-name> test 2
+--format=gnu-v3
+_ZZL3foo_2vE4var1
+foo()::var1
+# <local-source-name> test 3
+--format=gnu-v3
+_ZZL3foo_2vE4var1_0
+foo()::var1
+# <local-source-name> test 4
+--format=gnu-v3
+_ZZN7myspaceL3foo_1EvEN11localstruct1fEZNS_3fooEvE16otherlocalstruct
+myspace::foo()::localstruct::f(myspace::foo()::otherlocalstruct)
Index: libiberty/cp-demangle.c
===================================================================
--- libiberty/cp-demangle.c	(revision 124287)
+++ libiberty/cp-demangle.c	(working copy)
@@ -1100,6 +1100,9 @@
     case 'Z':
       return d_local_name (di);
 
+    case 'L':
+      return d_unqualified_name (di);
+	
     case 'S':
       {
 	int subst;
@@ -1220,7 +1223,8 @@
       if (IS_DIGIT (peek)
 	  || IS_LOWER (peek)
 	  || peek == 'C'
-	  || peek == 'D')
+	  || peek == 'D'
+	  || peek == 'L')
 	dc = d_unqualified_name (di);
       else if (peek == 'S')
 	dc = d_substitution (di, 1);
@@ -1254,6 +1258,9 @@
 /* <unqualified-name> ::= <operator-name>
                       ::= <ctor-dtor-name>
                       ::= <source-name>
+		      ::= <local-source-name> 
+
+    <local-source-name>	::= L <source-name> <discriminator>
 */
 
 static struct demangle_component *
@@ -1275,6 +1282,19 @@
     }
   else if (peek == 'C' || peek == 'D')
     return d_ctor_dtor_name (di);
+  else if (peek == 'L')
+    {
+      struct demangle_component * ret;
+
+      d_advance (di, 1);
+
+      ret = d_source_name (di);
+      if (ret == NULL)
+	return NULL;
+      if (! d_discriminator (di))
+	return NULL;
+      return ret;
+    }
   else
     return NULL;
 }
============================================================


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