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]

ptrmemfunc_vbit_in_delta was broken, patch strongly suggested for 3.0


I've just adapted the g++.abi/ptrmem.C test so that it would work
correctly on mn10300 and, to my surprise, it didn't.  I hadn't got
regressions on mn10300 when I tested my previous patch just because it
had been way too broken before.  Besides, apparently I goofed when
installing the previous patch, which didn't help :-(

Here's a patch that fixes the goof in get_member_function_from_ptrfunc
and fixes expand_ptrmemfunc_cst so that the correct value is stored in
pfn in the virtual case.  It also adjusts the ABI tests so that they
test for the right values on MN10300 and ARM/Thumb.  Hopefully, this
new failure will get someone that cares about ARM/Thumb to make the
decision I asked for moons ago, which was whether we should store the
vbit in the delta on all ARM variants, or only on those that support
Thumb.

Ok for branch and mainline?  Note that it is possible to prove that
behavior won't change on machines that store the vbit in pfn, and I've
actually tested it on i686-pc-linux-gnu native and cross mn10300-elf.

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* typeck.c (get_member_function_from_ptrfunc) [vbit_in_delta]:
	Don't clobber delta.
	(expand_ptrmemfunc_cst) [ptrmemfunc_vbit_in_delta]: Adjust pfn.

Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.337.2.6
diff -u -p -r1.337.2.6 typeck.c
--- gcc/cp/typeck.c 2001/06/06 16:12:44 1.337.2.6
+++ gcc/cp/typeck.c 2001/06/10 00:16:14
@@ -2936,9 +2936,6 @@ get_member_function_from_ptrfunc (instan
 	  abort ();
 	}
 
-      delta = cp_convert (ptrdiff_type_node,
-			  build_component_ref (function, delta_identifier,
-					       NULL_TREE, 0));
       /* DELTA2 is the amount by which to adjust the `this' pointer
 	 to find the vtbl.  */
       delta2 = delta;
@@ -6160,12 +6157,12 @@ expand_ptrmemfunc_cst (cst, delta, pfn)
 	 ptrmemfunc_vbit_in_delta, in which case delta is shifted
 	 left, and then incremented).  */
       *pfn = DECL_VINDEX (fn);
+      *pfn = fold (build (MULT_EXPR, integer_type_node, *pfn,
+			  TYPE_SIZE_UNIT (vtable_entry_type)));
 
       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
 	{
 	case ptrmemfunc_vbit_in_pfn:
-	  *pfn = fold (build (MULT_EXPR, integer_type_node, *pfn,
-			      TYPE_SIZE_UNIT (vtable_entry_type)));
 	  *pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
 			      integer_one_node));
 	  break;
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.old-deja/g++.abi/ptrmem.C: Take into account different
	representation on MN10300 and ARM/Thumb.

Index: gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C,v
retrieving revision 1.4
diff -u -p -r1.4 ptrmem.C
--- gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C 2000/06/04 21:12:25 1.4
+++ gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C 2001/06/10 00:16:14
@@ -1,6 +1,19 @@
 // Special g++ Options: -fno-strict-aliasing
 // Origin: Mark Mitchell <mark@codesourcery.com>
 
+/* Generally, the lowest bit of the ptr is used to indicate whether a
+   ptr-to-mem-func points to a virtual or a non-virtual member
+   function.  However, some platforms use all bits to encode a
+   function pointer.  Such platforms use the lowest bit of the delta,
+   that is shifted left by one bit.  */
+#if defined __MN10300__ || defined __arm__ || defined __thumb__
+#define ADJUST_PTRFN(func, virt) ((void (*)())(func))
+#define ADJUST_DELTA(delta, virt) (((delta) << 1) + !!(virt))
+#else
+#define ADJUST_PTRFN(func, virt) ((void (*)())((ptrdiff_t)(func) + !!(virt)))
+#define ADJUST_DELTA(delta, virt) (delta)
+#endif
+
 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
 
 // Check that pointers-to-member functions are represented correctly.
@@ -72,28 +85,28 @@ main ()
   // There should be no adjustment for the `T' version, and an
   // appropriate adjustment for the `S' version.
   y = &T::f;
-  if (yp->ptr != &_ZN1T1fEv)
+  if (yp->ptr != ADJUST_PTRFN (&_ZN1T1fEv, 0))
     return 5;
-  if (yp->adj != 0)
+  if (yp->adj != ADJUST_DELTA (0, 0))
     return 6;
   x = (sp) y;
-  if (xp->ptr != &_ZN1T1fEv)
+  if (xp->ptr != ADJUST_PTRFN (&_ZN1T1fEv, 0))
     return 7;
-  if (xp->adj != delta)
+  if (xp->adj != ADJUST_DELTA (delta, 0))
     return 8;
 
   // For a virtual function, we should see the vtable offset, plus
   // one.  `T::h' is in the second slot: the vtable pointer points to
   // the first virtual function.
   y = &T::h;
-  if ((ptrdiff_t) yp->ptr != sizeof (void *) + 1)
+  if (yp->ptr != ADJUST_PTRFN (sizeof (void *), 1))
     return 9;
-  if (yp->adj != 0)
+  if (yp->adj != ADJUST_DELTA (0, 1))
     return 10;
   x = (sp) y;
-  if ((ptrdiff_t) xp->ptr != sizeof (void *) + 1)
+  if (xp->ptr != ADJUST_PTRFN (sizeof (void *), 1))
     return 11;
-  if (xp->adj != delta)
+  if (xp->adj != ADJUST_DELTA (delta, 1))
     return 12;
 
   // Pointers-to-data-members should have the same size and alignment

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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