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


This patch fixes 21799 a latent deduction bug exposed by my implementation of DR214. We cannot deduce T as 'X const' against a pointer to constant member function, for instance. The CV qualifiers must match exactly. I took the same approach for a restrict qualifier.

booted & tested on i686-pc-linux-gnu, installed on mainline.
queued for 4.0.2

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

2005-07-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21799
	* pt.c (type_unification_real): Add is_method argument.  Use it
	for this pointer unification.
	(fn_type_unification): Adjust type_unification_real call.
	(unify): Likewise.

2005-07-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21799
	* g++.dg/template/unify8.C: New.
	* g++.dg/template/unify9.C: New.

Index: pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1012
diff -c -3 -p -r1.1012 pt.c
*** pt.c	7 Jul 2005 14:38:33 -0000	1.1012
--- pt.c	7 Jul 2005 14:57:02 -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);
  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, int);
  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,
*** 9177,9183 ****
       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:
--- 9177,9183 ----
       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:
*************** maybe_adjust_types_for_deduction (unific
*** 9285,9291 ****
  
     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,
--- 9285,9293 ----
  
     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,
*************** type_unification_real (tree tparms,
*** 9293,9299 ****
  		       tree xparms,
  		       tree xargs,
  		       int subr,
! 		       unification_kind_t strict)
  {
    tree parm, arg;
    int i;
--- 9295,9302 ----
  		       tree xparms,
  		       tree xargs,
  		       int subr,
! 		       unification_kind_t strict,
! 		       int is_method)
  {
    tree parm, arg;
    int i;
*************** type_unification_real (tree tparms,
*** 9345,9350 ****
--- 9348,9373 ----
  	   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
*************** unify (tree tparms, tree targs, tree par
*** 10249,10255 ****
  		 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
--- 10272,10279 ----
  		 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
Index: testsuite/g++.dg/template/unify8.C
===================================================================
RCS file: testsuite/g++.dg/template/unify8.C
diff -N testsuite/g++.dg/template/unify8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/unify8.C	8 Jul 2005 11:04:19 -0000
***************
*** 0 ****
--- 1,20 ----
+ // { dg-do link }
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 7 Jul 2005 <nathan@codesourcery.com>
+ 
+ // Origin:Wolfgang Bangerth <bangerth@dealii.org>
+ // PR 21799: deduction of cvqualifiers on member functions was wrong
+ 
+ template <class T> void f (T &,       void (T::*)()      ); 
+ template <class T> void f (const T &, void (T::*)() const) {} 
+  
+ struct X { 
+     void g() const {}
+ }; 
+  
+ const X *x; 
+  
+ int main () { 
+   f (*x, &X::g); 
+ }
Index: testsuite/g++.dg/template/unify9.C
===================================================================
RCS file: testsuite/g++.dg/template/unify9.C
diff -N testsuite/g++.dg/template/unify9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/unify9.C	8 Jul 2005 11:04:19 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 7 Jul 2005 <nathan@codesourcery.com>
+ 
+ // Origin:Wolfgang Bangerth <bangerth@dealii.org>
+ // PR 21799: deduction of cvqualifiers on member functions was wrong
+ 
+ template <class T> void f (T &,       void (T::*)()      ); 
+  
+ struct X { 
+     void g() const {}
+ }; 
+  
+ const X *x; 
+  
+ int main () { 
+   f (*x, &X::g);  // {  dg-error "no matching function" }
+ } 

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