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 23789


This patch fixes a problem with non-type template arguments.  We were
getting confused by an unnecessary NOP_EXPR (some aspects of templates
rely on very syntactic requirements, and casts are not allowed!) and
we had pointless, and actually harmful, duplication of
fold_non_dependent_expr in tsubst_template_arg.

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-09-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/23789
	* cvt.c (perform_qualification_conversions): Don't create
	unnecessary NOP_EXPRs.
	* pt.c (tsubst_template_arg): Use fold_non_dependent_expr.

2005-09-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/23789
	* g++.dg/template/nontype14.C: New test.

Index: gcc/cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.186
diff -c -5 -p -r1.186 cvt.c
*** gcc/cp/cvt.c	28 Jun 2005 21:55:10 -0000	1.186
--- gcc/cp/cvt.c	12 Sep 2005 19:52:43 -0000
*************** perform_qualification_conversions (tree 
*** 1207,1218 ****
  {
    tree expr_type;
  
    expr_type = TREE_TYPE (expr);
  
!   if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type)
!       && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type)))
      return build_nop (type, expr);
    else if (TYPE_PTR_TO_MEMBER_P (type)
  	   && TYPE_PTR_TO_MEMBER_P (expr_type)
  	   && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
  			   TYPE_PTRMEM_CLASS_TYPE (expr_type))
--- 1207,1220 ----
  {
    tree expr_type;
  
    expr_type = TREE_TYPE (expr);
  
!   if (same_type_p (type, expr_type))
!     return expr;
!   else if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type)
! 	   && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type)))
      return build_nop (type, expr);
    else if (TYPE_PTR_TO_MEMBER_P (type)
  	   && TYPE_PTR_TO_MEMBER_P (expr_type)
  	   && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
  			   TYPE_PTRMEM_CLASS_TYPE (expr_type))
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1031
diff -c -5 -p -r1.1031 pt.c
*** gcc/cp/pt.c	12 Sep 2005 04:03:47 -0000	1.1031
--- gcc/cp/pt.c	12 Sep 2005 19:52:45 -0000
*************** tsubst_template_arg (tree t, tree args, 
*** 5914,5949 ****
    else if (TYPE_P (t))
      r = tsubst (t, args, complain, in_decl);
    else
      {
        r = tsubst_expr (t, args, complain, in_decl);
! 
!       if (!uses_template_parms (r))
! 	{
! 	  /* Sometimes, one of the args was an expression involving a
! 	     template constant parameter, like N - 1.  Now that we've
! 	     tsubst'd, we might have something like 2 - 1.  This will
! 	     confuse lookup_template_class, so we do constant folding
! 	     here.  We have to unset processing_template_decl, to fool
! 	     tsubst_copy_and_build() into building an actual tree.  */
! 
! 	 /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
! 	    as simple as it's going to get, and trying to reprocess
! 	    the trees will break.  Once tsubst_expr et al DTRT for
! 	    non-dependent exprs, this code can go away, as the type
! 	    will always be set.  */
! 	  if (!TREE_TYPE (r))
! 	    {
! 	      int saved_processing_template_decl = processing_template_decl;
! 	      processing_template_decl = 0;
! 	      r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
! 					 tf_error, /*in_decl=*/NULL_TREE,
! 					 /*function_p=*/false);
! 	      processing_template_decl = saved_processing_template_decl;
! 	      r = fold (r);
! 	    }
! 	}
      }
    return r;
  }
  
  /* Substitute ARGS into the vector or list of template arguments T.  */
--- 5914,5924 ----
    else if (TYPE_P (t))
      r = tsubst (t, args, complain, in_decl);
    else
      {
        r = tsubst_expr (t, args, complain, in_decl);
!       r = fold_non_dependent_expr (r);
      }
    return r;
  }
  
  /* Substitute ARGS into the vector or list of template arguments T.  */
Index: gcc/testsuite/g++.dg/template/nontype14.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/nontype14.C
diff -N gcc/testsuite/g++.dg/template/nontype14.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/nontype14.C	12 Sep 2005 19:52:47 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/23789
+ 
+ template <int W> struct X { 
+   template <int W2> 
+   X< (W+(W&&W) > 1 ? W+(W&&W) : 1)+1> 
+   operator + (const X<W2>&) const; 
+ }; 
+  
+ template <int dummy> void foo() 
+ { 
+   X<6> A,B; 
+   A + B; 
+ }


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