cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Mar 2005 12:57:13 +0000 (12:57 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Mar 2005 12:57:13 +0000 (12:57 +0000)
PR c++/20186
* pt.c (contains_dependent_cast_p): New.
(fold_non_dependent_expr): Call it.
testsuite:
PR c++/20186
* g++.dg/template/non-dependent12.C: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96190 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/non-dependent12.C [new file with mode: 0644]

index a5dba31..8eec196 100644 (file)
@@ -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
index 14940b7..320cd84 100644 (file)
@@ -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;
 
index 3144250..46a7e7c 100644 (file)
@@ -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 (file)
index 0000000..73d7e94
--- /dev/null
@@ -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);
+}