This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix 20186
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 09 Mar 2005 13:15:38 +0000
- Subject: [PATCH] Fix 20186
- Organization: Codesourcery LLC
hi,
this patch fixes 20186 a recent c++ template regression. We can't
fold non-dependent expressions that contain something dependent. This
can happen with casts from a dependent type to a non-dependent type.
We abuse tsubst_copy to do the folding, and it goes horribly wrong.
This is really another case where we should mark such exprs as we build
them up ...
booted & tested on i686-pc-lonux-gnu, installed mainline and 4.0
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-03-08 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20186
* pt.c (contains_dependent_cast_p): New.
(fold_non_dependent_expr): Call it.
2005-03-09 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20186
* g++.dg/template/non-dependent12.C: New.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.979
diff -c -3 -p -r1.979 pt.c
*** cp/pt.c 5 Mar 2005 15:44:20 -0000 1.979
--- cp/pt.c 9 Mar 2005 12:35:40 -0000
*************** redeclare_class_template (tree type, tre
*** 3258,3263 ****
--- 3258,3309 ----
}
}
+ /* Return true if non-dependent expressions EXPR contains within it a
+ cast expression with a dependent argument. */
+
+ static bool
+ contains_dependent_cast_p (tree expr)
+ {
+ switch (TREE_CODE (expr))
+ {
+ case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ {
+ tree op = TREE_OPERAND (expr, 0);
+
+ if (op && (type_dependent_expression_p (op)
+ || value_dependent_expression_p (op)))
+ return true;
+ }
+ break;
+
+ case TREE_LIST:
+ /* The operands of a CALL_EXPR are held as a list. */
+ for (; expr; expr = TREE_CHAIN (expr))
+ if (contains_dependent_cast_p (TREE_VALUE (expr)))
+ return true;
+ return false;
+
+ default:
+ break;
+ }
+
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
+ {
+ int ix;
+
+ for (ix = TREE_CODE_LENGTH (TREE_CODE (expr)); ix--;)
+ if (TREE_OPERAND (expr, ix)
+ && contains_dependent_cast_p (TREE_OPERAND (expr, ix)))
+ return true;
+ }
+
+ return false;
+ }
+
/* Simplify EXPR if it is a non-dependent expression. Returns the
(possibly simplified) expression. */
*************** fold_non_dependent_expr (tree expr)
*** 3273,3279 ****
as two declarations of the same function, for example. */
if (processing_template_decl
&& !type_dependent_expression_p (expr)
! && !value_dependent_expression_p (expr))
{
HOST_WIDE_INT saved_processing_template_decl;
--- 3319,3326 ----
as two declarations of the same function, for example. */
if (processing_template_decl
&& !type_dependent_expression_p (expr)
! && !value_dependent_expression_p (expr)
! && !contains_dependent_cast_p (expr))
{
HOST_WIDE_INT saved_processing_template_decl;
Index: testsuite/g++.dg/template/non-dependent12.C
===================================================================
RCS file: testsuite/g++.dg/template/non-dependent12.C
diff -N testsuite/g++.dg/template/non-dependent12.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/non-dependent12.C 9 Mar 2005 12:35:40 -0000
***************
*** 0 ****
--- 1,10 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 8 Mar 2005 <nathan@codesourcery.com>
+
+ // PR 20186: ICE
+ // Origin: Jan Dvorak <jan.dvorak@kraxnet.cz>
+
+ template<typename T> void foo(T &t)
+ {
+ int i = static_cast<int>(t);
+ }