re PR c++/20186 (ICE with static_cast and type dependent variable (templates))

cp:
	PR c++/20186
	* pt.c (contains_dependent_cast_p): Remove.
	(fold_non_dependent_expr): Don't use it.
	(value_dependent_expression_p): Use a switch statement.
	reference_exprs can be dependent.

From-SVN: r96605
This commit is contained in:
Nathan Sidwell 2005-03-17 13:26:39 +00:00 committed by Nathan Sidwell
parent 52eb57dfb1
commit 7416ab0243
2 changed files with 112 additions and 142 deletions

View File

@ -1,3 +1,11 @@
2005-03-17 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20186
* pt.c (contains_dependent_cast_p): Remove.
(fold_non_dependent_expr): Don't use it.
(value_dependent_expression_p): Use a switch statement.
reference_exprs can be dependent.
2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/4403 PR c++/4403

View File

@ -3273,52 +3273,6 @@ 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 /* Simplify EXPR if it is a non-dependent expression. Returns the
(possibly simplified) expression. */ (possibly simplified) expression. */
@ -3334,8 +3288,7 @@ fold_non_dependent_expr (tree expr)
as two declarations of the same function, for example. */ as two declarations of the same function, for example. */
if (processing_template_decl if (processing_template_decl
&& !type_dependent_expression_p (expr) && !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; HOST_WIDE_INT saved_processing_template_decl;
@ -12018,119 +11971,132 @@ value_dependent_expression_p (tree expression)
return false; return false;
/* A name declared with a dependent type. */ /* A name declared with a dependent type. */
if (TREE_CODE (expression) == IDENTIFIER_NODE if (DECL_P (expression) && type_dependent_expression_p (expression))
|| (DECL_P (expression)
&& type_dependent_expression_p (expression)))
return true; return true;
/* A non-type template parameter. */
if ((TREE_CODE (expression) == CONST_DECL switch (TREE_CODE (expression))
&& DECL_TEMPLATE_PARM_P (expression))
|| TREE_CODE (expression) == TEMPLATE_PARM_INDEX)
return true;
/* A constant with integral or enumeration type and is initialized
with an expression that is value-dependent. */
if (TREE_CODE (expression) == VAR_DECL
&& DECL_INITIAL (expression)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
&& value_dependent_expression_p (DECL_INITIAL (expression)))
return true;
/* These expressions are value-dependent if the type to which the
cast occurs is dependent or the expression being casted is
value-dependent. */
if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
|| TREE_CODE (expression) == STATIC_CAST_EXPR
|| TREE_CODE (expression) == CONST_CAST_EXPR
|| TREE_CODE (expression) == REINTERPRET_CAST_EXPR
|| TREE_CODE (expression) == CAST_EXPR)
{ {
tree type = TREE_TYPE (expression); case IDENTIFIER_NODE:
if (dependent_type_p (type)) /* A name that has not been looked up -- must be dependent. */
return true; return true;
/* A functional cast has a list of operands. */
expression = TREE_OPERAND (expression, 0);
if (!expression)
{
/* If there are no operands, it must be an expression such
as "int()". This should not happen for aggregate types
because it would form non-constant expressions. */
gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
return false; case TEMPLATE_PARM_INDEX:
} /* A non-type template parm. */
if (TREE_CODE (expression) == TREE_LIST) return true;
{
do case CONST_DECL:
{ /* A non-type template parm. */
if (DECL_TEMPLATE_PARM_P (expression))
return true;
return false;
case VAR_DECL:
/* A constant with integral or enumeration type and is initialized
with an expression that is value-dependent. */
if (DECL_INITIAL (expression)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
&& value_dependent_expression_p (DECL_INITIAL (expression)))
return true;
return false;
case DYNAMIC_CAST_EXPR:
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CAST_EXPR:
/* These expressions are value-dependent if the type to which
the cast occurs is dependent or the expression being casted
is value-dependent. */
{
tree type = TREE_TYPE (expression);
if (dependent_type_p (type))
return true;
/* A functional cast has a list of operands. */
expression = TREE_OPERAND (expression, 0);
if (!expression)
{
/* If there are no operands, it must be an expression such
as "int()". This should not happen for aggregate types
because it would form non-constant expressions. */
gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
return false;
}
if (TREE_CODE (expression) == TREE_LIST)
{
for (; expression; expression = TREE_CHAIN (expression))
if (value_dependent_expression_p (TREE_VALUE (expression))) if (value_dependent_expression_p (TREE_VALUE (expression)))
return true; return true;
expression = TREE_CHAIN (expression); return false;
} }
while (expression);
return false;
}
else
return value_dependent_expression_p (expression); return value_dependent_expression_p (expression);
} }
/* A `sizeof' expression is value-dependent if the operand is
type-dependent. */ case SIZEOF_EXPR:
if (TREE_CODE (expression) == SIZEOF_EXPR case ALIGNOF_EXPR:
|| TREE_CODE (expression) == ALIGNOF_EXPR) /* A `sizeof' expression is value-dependent if the operand is
{ type-dependent. */
expression = TREE_OPERAND (expression, 0); expression = TREE_OPERAND (expression, 0);
if (TYPE_P (expression)) if (TYPE_P (expression))
return dependent_type_p (expression); return dependent_type_p (expression);
return type_dependent_expression_p (expression); return type_dependent_expression_p (expression);
}
if (TREE_CODE (expression) == SCOPE_REF)
return dependent_scope_ref_p (expression, value_dependent_expression_p);
if (TREE_CODE (expression) == COMPONENT_REF)
return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
|| value_dependent_expression_p (TREE_OPERAND (expression, 1)));
/* A CALL_EXPR is value-dependent if any argument is case SCOPE_REF:
value-dependent. Why do we have to handle CALL_EXPRs in this return dependent_scope_ref_p (expression, value_dependent_expression_p);
function at all? First, some function calls, those for which
value_dependent_expression_p is true, man appear in constant
expressions. Second, there appear to be bugs which result in
other CALL_EXPRs reaching this point. */
if (TREE_CODE (expression) == CALL_EXPR)
{
tree function = TREE_OPERAND (expression, 0);
tree args = TREE_OPERAND (expression, 1);
if (value_dependent_expression_p (function)) case COMPONENT_REF:
return true; return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
else if (! args) || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
return false;
else if (TREE_CODE (args) == TREE_LIST) case CALL_EXPR:
{ /* A CALL_EXPR is value-dependent if any argument is
do value-dependent. Why do we have to handle CALL_EXPRs in this
{ function at all? First, some function calls, those for which
value_dependent_expression_p is true, man appear in constant
expressions. Second, there appear to be bugs which result in
other CALL_EXPRs reaching this point. */
{
tree function = TREE_OPERAND (expression, 0);
tree args = TREE_OPERAND (expression, 1);
if (value_dependent_expression_p (function))
return true;
if (! args)
return false;
if (TREE_CODE (args) == TREE_LIST)
{
for (; args; args = TREE_CHAIN (args))
if (value_dependent_expression_p (TREE_VALUE (args))) if (value_dependent_expression_p (TREE_VALUE (args)))
return true; return true;
args = TREE_CHAIN (args); return false;
} }
while (args);
return false;
}
else
return value_dependent_expression_p (args); return value_dependent_expression_p (args);
} }
/* A constant expression is value-dependent if any subexpression is
value-dependent. */ default:
if (EXPR_P (expression)) /* A constant expression is value-dependent if any subexpression is
{ value-dependent. */
switch (TREE_CODE_CLASS (TREE_CODE (expression))) switch (TREE_CODE_CLASS (TREE_CODE (expression)))
{ {
case tcc_reference:
case tcc_unary: case tcc_unary:
return (value_dependent_expression_p return (value_dependent_expression_p
(TREE_OPERAND (expression, 0))); (TREE_OPERAND (expression, 0)));
case tcc_comparison: case tcc_comparison:
case tcc_binary: case tcc_binary:
return ((value_dependent_expression_p return ((value_dependent_expression_p
(TREE_OPERAND (expression, 0))) (TREE_OPERAND (expression, 0)))
|| (value_dependent_expression_p || (value_dependent_expression_p
(TREE_OPERAND (expression, 1)))); (TREE_OPERAND (expression, 1))));
case tcc_expression: case tcc_expression:
{ {
int i; int i;
@ -12145,16 +12111,12 @@ value_dependent_expression_p (tree expression)
return true; return true;
return false; return false;
} }
case tcc_reference:
case tcc_statement:
/* These cannot be value dependent. */
return false;
default: default:
gcc_unreachable (); break;
} }
} }
/* The expression is not value-dependent. */ /* The expression is not value-dependent. */
return false; return false;
} }