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]

PATCH COMMITTED: Demangler fix for PR 28797


This patch to the demangler fixes a case in PR 28797 where the
demangler failed to demangle a symbol generated by g++.  It's not
clear whether this PR is a regression or not--I haven't gone back to
check the old demangler.  But the patch is simple and self-contained,
and will only affect the demangling of this rather obscure case, so I
went ahead and applied it.  Please let me know if you feel that I
acted incorrectly.

This patch is actually a tweak to a workaround for what I believe is
an ABI error on the part of g++.  The ABI error can be seen in the
handling of METHOD_TYPE in write_function_type() in cp/mangle.c.  It
calls write_CV_qualifiers_for_type() but fails to call
add_substitution().  Compare to the handling of
write_CV_qualifiers_for_type() in write_type().  The demangler has to
work around this bug by doing its own special handling of CV
qualifiers for pointers to member.  My error was that I applied the
special handling to all pointers to member, but it is only applicable
to pointers to member functions, not to pointers to member variables.

It is not clear whether it is worth fixing this bug in g++.  However,
it would be interesting to see what other compilers do with these test
cases--to see whether they produce the same symbols that g++ produces:

void f(int const A::*, int const A::* const*)
{
  return;
}

class G { };
class H { };
template<class G> class what { };
template<class G> class what2 { };
void r(int (G::*)(), int (G::*)() const, G, int (H::*)(), int (G::*)(), what<G const>, what2<G const>, int (G::*)() const) { }

Tested with bootstrap and testsuite run on i686-pc-linux-gnu.

Ian


2006-08-27  Ian Lance Taylor  <ian@airs.com>

	PR other/28797
	* cp-demangle.c (d_pointer_to_member_type): Do add a substitution
	for a qualified member which is not a function.
	* testsuite/demangle-expected: Add test case.


Index: cp-demangle.c
===================================================================
--- cp-demangle.c	(revision 116492)
+++ cp-demangle.c	(working copy)
@@ -2081,13 +2081,22 @@ d_pointer_to_member_type (struct d_info 
      g++ does not work that way.  g++ treats only the CV-qualified
      member function as a substitution source.  FIXME.  So to work
      with g++, we need to pull off the CV-qualifiers here, in order to
-     avoid calling add_substitution() in cplus_demangle_type().  */
+     avoid calling add_substitution() in cplus_demangle_type().  But
+     for a CV-qualified member which is not a function, g++ does
+     follow the ABI, so we need to handle that case here by calling
+     d_add_substitution ourselves.  */
 
   pmem = d_cv_qualifiers (di, &mem, 1);
   if (pmem == NULL)
     return NULL;
   *pmem = cplus_demangle_type (di);
 
+  if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
+    {
+      if (! d_add_substitution (di, mem))
+	return NULL;
+    }
+
   return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
 }
 
Index: testsuite/demangle-expected
===================================================================
--- testsuite/demangle-expected	(revision 116492)
+++ testsuite/demangle-expected	(working copy)
@@ -3805,3 +3805,9 @@ java::lang::Math::acos(double)double
 _Z4makeI7FactoryiET_IT0_Ev
 make<Factory, int>()Factory<int>
 make<Factory, int>
+#
+# From PR 28797
+--format=auto --no-params
+_Z1fM1AKiPKS1_
+f(int const A::*, int const A::* const*)
+f


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