diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/non-dependent12.C | 10 |
4 files changed, 69 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a5dba31ddef..8eec1963d46 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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-08 Mark Mitchell <mark@codesourcery.com> PR c++/20142 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 14940b75671..320cd84522b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3258,6 +3258,52 @@ redeclare_class_template (tree type, tree parms) } } +/* 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. */ @@ -3273,7 +3319,8 @@ fold_non_dependent_expr (tree expr) as two declarations of the same function, for example. */ if (processing_template_decl && !type_dependent_expression_p (expr) - && !value_dependent_expression_p (expr)) + && !value_dependent_expression_p (expr) + && !contains_dependent_cast_p (expr)) { HOST_WIDE_INT saved_processing_template_decl; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 314425094cd..46a7e7c7674 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-09 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/20186 + * g++.dg/template/non-dependent12.C: New. + 2005-03-08 Mark Mitchell <mark@codesourcery.com> PR c++/20142 diff --git a/gcc/testsuite/g++.dg/template/non-dependent12.C b/gcc/testsuite/g++.dg/template/non-dependent12.C new file mode 100644 index 00000000000..73d7e949766 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent12.C @@ -0,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); +} |