OSDN Git Service

PR c++/20208
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 14940b7..2ad20b3 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;
 
@@ -6468,6 +6515,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          SET_DECL_TEMPLATE_PARM_P (r);
 
        type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       type = type_decays_to (type);
        TREE_TYPE (r) = type;
        cp_apply_type_quals_to_decl (cp_type_quals (type), r);
 
@@ -11089,6 +11137,7 @@ regenerate_decl_from_template (tree decl, tree tmpl)
            DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
          parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
                              NULL_TREE);
+         parm_type = type_decays_to (parm_type);
          if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
            TREE_TYPE (decl_parm) = parm_type;
          decl_parm = TREE_CHAIN (decl_parm);