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] Fix 21799/8271


I've installed this patch to revert my fix for 21799 and install Giovanni's fix for 8271, which is better. I tweaked Giovanni's patch slightly to avoid the fall through, and use EXACT_MATCH, because that's what we're checking.

I spent a considerable time trying to change our METHOD_TYPE representation to hold the cv qualifiers on the METHOD_TYPE node too. This required considerable ugly hackery. I have come to the conclusion that the this pointer qualifiers do not belong on that node, for they do not behave like other cv qualifiers.

I'm installing Giovanni's fix on the 4.0 branch too.

booted & tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-08-12  Giovanni Bajo  <giovannibajo@libero.it>
	    Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21799
	PR c++/8271
        * pt.c (unify) <METHOD_TYPE>: Check this-pointer cv-qualifiers
	explicitly.
	
2005-08-12  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21799
	Revert my 2005-07-08 patch
	* pt.c (type_unification_real): Remove is_method_argument and
	assoicated checks.
	(fn_type_unification, unify): Adjust type_unification_real calls.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1021
diff -c -3 -p -r1.1021 pt.c
*** cp/pt.c	6 Aug 2005 22:38:42 -0000	1.1021
--- cp/pt.c	11 Aug 2005 11:01:50 -0000
*************** static tree add_outermost_template_args 
*** 109,115 ****
  static bool check_instantiated_args (tree, tree, tsubst_flags_t);
  static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
  static int  type_unification_real (tree, tree, tree, tree,
! 				   int, unification_kind_t, int);
  static void note_template_header (int);
  static tree convert_nontype_argument_function (tree, tree);
  static tree convert_nontype_argument (tree, tree);
--- 109,115 ----
  static bool check_instantiated_args (tree, tree, tsubst_flags_t);
  static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
  static int  type_unification_real (tree, tree, tree, tree,
! 				   int, unification_kind_t);
  static void note_template_header (int);
  static tree convert_nontype_argument_function (tree, tree);
  static tree convert_nontype_argument (tree, tree);
*************** fn_type_unification (tree fn,
*** 9197,9203 ****
       event.  */
    result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
  				  targs, parms, args, /*subr=*/0,
! 				  strict, 0);
  
    if (result == 0)
      /* All is well so far.  Now, check:
--- 9197,9203 ----
       event.  */
    result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
  				  targs, parms, args, /*subr=*/0,
! 				  strict);
  
    if (result == 0)
      /* All is well so far.  Now, check:
*************** maybe_adjust_types_for_deduction (unific
*** 9305,9313 ****
  
     If SUBR is 1, we're being called recursively (to unify the
     arguments of a function or method parameter of a function
!    template).  If IS_METHOD is true, XPARMS are the parms of a
!    member function, and special rules apply to cv qualification
!    deduction on the this parameter.  */
  
  static int
  type_unification_real (tree tparms,
--- 9305,9311 ----
  
     If SUBR is 1, we're being called recursively (to unify the
     arguments of a function or method parameter of a function
!    template). */
  
  static int
  type_unification_real (tree tparms,
*************** type_unification_real (tree tparms,
*** 9315,9322 ****
  		       tree xparms,
  		       tree xargs,
  		       int subr,
! 		       unification_kind_t strict,
! 		       int is_method)
  {
    tree parm, arg;
    int i;
--- 9313,9319 ----
  		       tree xparms,
  		       tree xargs,
  		       int subr,
! 		       unification_kind_t strict)
  {
    tree parm, arg;
    int i;
*************** type_unification_real (tree tparms,
*** 9368,9393 ****
  	   template args from other function args.  */
  	continue;
  
-       if (is_method)
- 	{
- 	  /* The cv qualifiers on the this pointer argument must match
-  	     exactly.  We cannot deduce a T as const X against a const
-  	     member function for instance.  */
- 	  gcc_assert (TREE_CODE (parm) == POINTER_TYPE);
- 	  gcc_assert (TREE_CODE (arg) == POINTER_TYPE);
- 	  /* The restrict qualifier will be on the pointer.  */
- 	  if (cp_type_quals (parm) != cp_type_quals (arg))
- 	    return 1;
- 	  parm = TREE_TYPE (parm);
- 	  arg = TREE_TYPE (arg);
- 	  if (cp_type_quals (parm) != cp_type_quals (arg))
- 	    return 1;
- 	  
- 	  parm = TYPE_MAIN_VARIANT (parm);
- 	  arg = TYPE_MAIN_VARIANT (arg);
- 	  is_method = 0;
- 	}
-       
        /* Conversions will be performed on a function argument that
  	 corresponds with a function parameter that contains only
  	 non-deducible template parameters and explicitly specified
--- 9365,9370 ----
*************** unify (tree tparms, tree targs, tree par
*** 10288,10299 ****
        if (TREE_CODE (arg) != TREE_CODE (parm))
  	return 1;
  
        if (unify (tparms, targs, TREE_TYPE (parm),
  		 TREE_TYPE (arg), UNIFY_ALLOW_NONE))
  	return 1;
        return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
! 				    TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
! 				    TREE_CODE (parm) == METHOD_TYPE);
  
      case OFFSET_TYPE:
        /* Unify a pointer to member with a pointer to member function, which
--- 10265,10286 ----
        if (TREE_CODE (arg) != TREE_CODE (parm))
  	return 1;
  
+       /* CV qualifications for methods can never be deduced, they must
+   	 match exactly.  We need to check them explicitly here,
+   	 because type_unification_real treats them as any other
+   	 cvqualified parameter.  */
+       if (TREE_CODE (parm) == METHOD_TYPE
+ 	  && (!check_cv_quals_for_unify
+ 	      (UNIFY_ALLOW_NONE,
+ 	       TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+ 	       TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
+ 	return 1;
+ 
        if (unify (tparms, targs, TREE_TYPE (parm),
  		 TREE_TYPE (arg), UNIFY_ALLOW_NONE))
  	return 1;
        return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
! 				    TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT);
  
      case OFFSET_TYPE:
        /* Unify a pointer to member with a pointer to member function, which
// { dg-do compile }
// Origin: Wolfgang Bangerth <bangerth at ticam dot utexas dot edu>
//     and Rene Fonseca <fonseca at mip dot sdu dot dk>
// PR c++/8271: Check cv-qualifiers while unifying pointer to member
//  functions.

struct MyClass {
  void mMethod() throw() {}
  void cMethod() const throw() {}
  void vMethod() volatile throw() {}
  void cvMethod() const volatile throw() {}
};

template<class CLASS>
void mFunction(void (CLASS::* method)()) {}

template<class CLASS>
void cFunction(void (CLASS::* method)() const) {}

template<class CLASS>
void vFunction(void (CLASS::* method)() volatile) {}

template<class CLASS>
void cvFunction(void (CLASS::* method)() const volatile) {}

int main() {
  mFunction(&MyClass::mMethod);
  mFunction(&MyClass::cMethod);    // { dg-error "no matching function" }
  mFunction(&MyClass::vMethod);    // { dg-error "no matching function" }
  mFunction(&MyClass::cvMethod);   // { dg-error "no matching function" }

  cFunction(&MyClass::mMethod);    // { dg-error "no matching function" }
  cFunction(&MyClass::cMethod);
  cFunction(&MyClass::vMethod);    // { dg-error "no matching function" }
  cFunction(&MyClass::cvMethod);   // { dg-error "no matching function" }

  vFunction(&MyClass::mMethod);    // { dg-error "no matching function" }
  vFunction(&MyClass::cMethod);    // { dg-error "no matching function" }
  vFunction(&MyClass::vMethod);
  vFunction(&MyClass::cvMethod);   // { dg-error "no matching function" }

  cvFunction(&MyClass::mMethod);   // { dg-error "no matching function" }
  cvFunction(&MyClass::cMethod);   // { dg-error "no matching function" }
  cvFunction(&MyClass::vMethod);   // { dg-error "no matching function" }
  cvFunction(&MyClass::cvMethod);

  return 0;
}

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