This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 23789
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 12 Sep 2005 15:42:07 -0700
- Subject: C++ PATCH: PR 23789
- Reply-to: mark at codesourcery dot com
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;
+ }