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]

C++ PATCH: PR 21614


This patch fixes PR c++/21614, a wrong-code regression in 4.0.

The problem stems from Nathan's changes to make us not allocate binfos
for incomplete types, which is, of course, a win.  But, that means
that lookup_base cannot return a sensible value for an incomplete
type, so we must trying to convert to a base class of an incomplete
type.  In most cases, we would never try to do that, because the use
of incomplete type would be an error -- but in this particular case,
it is valid to use a pointer-to-member of incomplete type.

Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.0 branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-05-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/21614
	* typeck.c (get_member_function_from_ptrfunc): Do not attempt
	conversions to base classes of incomplete types.

2005-05-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/21614
	* g++.dg/expr/ptrmem6.C: New test.
	* g++.dg/expr/ptrmem6a.C: Likewise.

Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.629
diff -c -5 -p -r1.629 typeck.c
*** cp/typeck.c	24 May 2005 22:22:33 -0000	1.629
--- cp/typeck.c	28 May 2005 02:14:46 -0000
*************** get_member_function_from_ptrfunc (tree *
*** 2344,2361 ****
  
  	default:
  	  gcc_unreachable ();
  	}
  
!       /* Convert down to the right base before using the instance.  First
!          use the type...  */
        basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
!       basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
! 			      basetype, ba_check, NULL);
!       instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1);
!       if (instance_ptr == error_mark_node)
! 	return error_mark_node;
        /* ...and then the delta in the PMF.  */
        instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
  			     instance_ptr, delta);
  
        /* Hand back the adjusted 'this' argument to our caller.  */
--- 2344,2370 ----
  
  	default:
  	  gcc_unreachable ();
  	}
  
!       /* Convert down to the right base before using the instance.  A
! 	 special case is that in a pointer to member of class C, C may
! 	 be incomplete.  In that case, the function will of course be
! 	 a member of C, and no conversion is required.  In fact,
! 	 lookup_base will fail in that case, because incomplete
! 	 classes do not have BINFOs.  */ 
        basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
!       if (!same_type_ignoring_top_level_qualifiers_p 
! 	  (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
! 	{
! 	  basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
! 				  basetype, ba_check, NULL);
! 	  instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 
! 					  1);
! 	  if (instance_ptr == error_mark_node)
! 	    return error_mark_node;
! 	}
        /* ...and then the delta in the PMF.  */
        instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
  			     instance_ptr, delta);
  
        /* Hand back the adjusted 'this' argument to our caller.  */
Index: testsuite/g++.dg/expr/ptrmem6.C
===================================================================
RCS file: testsuite/g++.dg/expr/ptrmem6.C
diff -N testsuite/g++.dg/expr/ptrmem6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/ptrmem6.C	28 May 2005 02:14:46 -0000
***************
*** 0 ****
--- 1,12 ----
+ // PR C++/21614
+ // { dg-additional-sources "ptrmem6a.C" }
+ // { dg-do run }
+ 
+ extern struct Z *p; 
+ extern int (Z::*m) (); 
+  
+ int main () { 
+   if ((p->*m)() == 7)
+     return 0;
+   return 1;
+ }
Index: testsuite/g++.dg/expr/ptrmem6a.C
===================================================================
RCS file: testsuite/g++.dg/expr/ptrmem6a.C
diff -N testsuite/g++.dg/expr/ptrmem6a.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/ptrmem6a.C	28 May 2005 02:14:46 -0000
***************
*** 0 ****
--- 1,9 ----
+ struct Z {
+   int f();
+ };
+ 
+ int Z::f() { return 7; }
+ 
+ struct Z z;
+ int (Z::*m)() = &Z::f;
+ struct Z*p = &z;


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