Commit 9f509004 by Richard Guenther Committed by Richard Biener

tree-cfg.c (verify_types_in_gimple_assign): Rename to ...

2008-09-17  Richard Guenther  <rguenther@suse.de>

	* tree-cfg.c (verify_types_in_gimple_assign): Rename to ...
	(verify_gimple_assign): ... this.  Split into ...
	(verify_gimple_assign_unary): ... this,
	(verify_gimple_assign_binary): ... that,
	(verify_gimple_assign_single): ... and this.
	(verify_types_in_gimple_stmt): Call verify_gimple_assign.
	Fix GIMPLE_CHANGE_DYNAMIC_TYPE handling.
	(verify_types_in_gimple_min_lval): Handle TARGET_MEM_REF.
	(verify_types_in_gimple_reference): Be forgiving with
	VIEW_CONVERT_EXPRs.
	(verify_gimple_phi): Deal with virtual operands.

	* tree.def (PREDICT_EXPR): Change to tcc_expression.

From-SVN: r140431
parent 2700cb86
2008-09-17 Richard Guenther <rguenther@suse.de>
* tree-cfg.c (verify_types_in_gimple_assign): Rename to ...
(verify_gimple_assign): ... this. Split into ...
(verify_gimple_assign_unary): ... this,
(verify_gimple_assign_binary): ... that,
(verify_gimple_assign_single): ... and this.
(verify_types_in_gimple_stmt): Call verify_gimple_assign.
Fix GIMPLE_CHANGE_DYNAMIC_TYPE handling.
(verify_types_in_gimple_min_lval): Handle TARGET_MEM_REF.
(verify_types_in_gimple_reference): Be forgiving with
VIEW_CONVERT_EXPRs.
(verify_gimple_phi): Deal with virtual operands.
* tree.def (PREDICT_EXPR): Change to tcc_expression.
2008-09-17 Andrew Pinski <andrew_pinski@playstation.sony.com> 2008-09-17 Andrew Pinski <andrew_pinski@playstation.sony.com>
* tree.c (get_callee_fndecl): Don't call the language hook. * tree.c (get_callee_fndecl): Don't call the language hook.
......
...@@ -3035,14 +3035,17 @@ verify_types_in_gimple_min_lval (tree expr) ...@@ -3035,14 +3035,17 @@ verify_types_in_gimple_min_lval (tree expr)
if (is_gimple_id (expr)) if (is_gimple_id (expr))
return false; return false;
if (TREE_CODE (expr) != INDIRECT_REF if (!INDIRECT_REF_P (expr)
&& TREE_CODE (expr) != ALIGN_INDIRECT_REF && TREE_CODE (expr) != TARGET_MEM_REF)
&& TREE_CODE (expr) != MISALIGNED_INDIRECT_REF)
{ {
error ("invalid expression for min lvalue"); error ("invalid expression for min lvalue");
return true; return true;
} }
/* TARGET_MEM_REFs are strange beasts. */
if (TREE_CODE (expr) == TARGET_MEM_REF)
return false;
op = TREE_OPERAND (expr, 0); op = TREE_OPERAND (expr, 0);
if (!is_gimple_val (op)) if (!is_gimple_val (op))
{ {
...@@ -3131,6 +3134,9 @@ verify_types_in_gimple_reference (tree expr) ...@@ -3131,6 +3134,9 @@ verify_types_in_gimple_reference (tree expr)
/* For VIEW_CONVERT_EXPRs which are allowed here, too, there /* For VIEW_CONVERT_EXPRs which are allowed here, too, there
is nothing to verify. Gross mismatches at most invoke is nothing to verify. Gross mismatches at most invoke
undefined behavior. */ undefined behavior. */
if (TREE_CODE (expr) == VIEW_CONVERT_EXPR
&& !handled_component_p (op))
return false;
expr = op; expr = op;
} }
...@@ -3257,45 +3263,50 @@ verify_gimple_comparison (tree type, tree op0, tree op1) ...@@ -3257,45 +3263,50 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
return false; return false;
} }
/* Verify the contents of a GIMPLE_ASSIGN STMT. Returns true when there /* Verify a gimple assignment statement STMT with an unary rhs.
is a problem, otherwise false. Returns true if anything is wrong. */
Verify that the types of the LHS and the RHS operands are
compatible. This verification largely depends on what kind of
operation is done on the RHS of the assignment. It is not always
the case that all the types of the operands must match (e.g., 'a =
(unsigned long) b' or 'ptr = ptr + 1'). */
static bool static bool
verify_types_in_gimple_assign (gimple stmt) verify_gimple_assign_unary (gimple stmt)
{ {
enum tree_code rhs_code = gimple_assign_rhs_code (stmt); enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree lhs = gimple_assign_lhs (stmt); tree lhs = gimple_assign_lhs (stmt);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs2 = (gimple_num_ops (stmt) == 3) ? gimple_assign_rhs2 (stmt) : NULL;
tree lhs_type = TREE_TYPE (lhs); tree lhs_type = TREE_TYPE (lhs);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs1_type = TREE_TYPE (rhs1); tree rhs1_type = TREE_TYPE (rhs1);
tree rhs2_type = (rhs2) ? TREE_TYPE (rhs2) : NULL;
/* Special codes we cannot handle via their class. */ if (!is_gimple_reg (lhs)
&& !(optimize == 0
&& TREE_CODE (lhs_type) == COMPLEX_TYPE))
{
error ("non-register as LHS of unary operation");
return true;
}
if (!is_gimple_val (rhs1))
{
error ("invalid operand in unary operation");
return true;
}
/* First handle conversions. */
switch (rhs_code) switch (rhs_code)
{ {
CASE_CONVERT: CASE_CONVERT:
{ {
if (!is_gimple_val (rhs1))
{
error ("invalid operand in conversion");
return true;
}
/* Allow conversions between integral types and pointers only if /* Allow conversions between integral types and pointers only if
there is no sign or zero extension involved. */ there is no sign or zero extension involved.
if (((POINTER_TYPE_P (lhs_type) && INTEGRAL_TYPE_P (rhs1_type)) For targets were the precision of sizetype doesn't match that
|| (POINTER_TYPE_P (rhs1_type) && INTEGRAL_TYPE_P (lhs_type))) of pointers we need to allow arbitrary conversions from and
&& (TYPE_PRECISION (lhs_type) == TYPE_PRECISION (rhs1_type) to sizetype. */
/* For targets were the precision of sizetype doesn't if ((POINTER_TYPE_P (lhs_type)
match that of pointers we need the following. */ && INTEGRAL_TYPE_P (rhs1_type)
|| lhs_type == sizetype || rhs1_type == sizetype)) && (TYPE_PRECISION (lhs_type) >= TYPE_PRECISION (rhs1_type)
|| rhs1_type == sizetype))
|| (POINTER_TYPE_P (rhs1_type)
&& INTEGRAL_TYPE_P (lhs_type)
&& (TYPE_PRECISION (rhs1_type) >= TYPE_PRECISION (lhs_type)
|| lhs_type == sizetype)))
return false; return false;
/* Allow conversion from integer to offset type and vice versa. */ /* Allow conversion from integer to offset type and vice versa. */
...@@ -3320,12 +3331,6 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3320,12 +3331,6 @@ verify_types_in_gimple_assign (gimple stmt)
case FIXED_CONVERT_EXPR: case FIXED_CONVERT_EXPR:
{ {
if (!is_gimple_val (rhs1))
{
error ("invalid operand in conversion");
return true;
}
if (!valid_fixed_convert_types_p (lhs_type, rhs1_type) if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
&& !valid_fixed_convert_types_p (rhs1_type, lhs_type)) && !valid_fixed_convert_types_p (rhs1_type, lhs_type))
{ {
...@@ -3340,12 +3345,6 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3340,12 +3345,6 @@ verify_types_in_gimple_assign (gimple stmt)
case FLOAT_EXPR: case FLOAT_EXPR:
{ {
if (!is_gimple_val (rhs1))
{
error ("invalid operand in int to float conversion");
return true;
}
if (!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type)) if (!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type))
{ {
error ("invalid types in conversion to floating point"); error ("invalid types in conversion to floating point");
...@@ -3359,12 +3358,6 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3359,12 +3358,6 @@ verify_types_in_gimple_assign (gimple stmt)
case FIX_TRUNC_EXPR: case FIX_TRUNC_EXPR:
{ {
if (!is_gimple_val (rhs1))
{
error ("invalid operand in float to int conversion");
return true;
}
if (!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type)) if (!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type))
{ {
error ("invalid types in conversion to integer"); error ("invalid types in conversion to integer");
...@@ -3376,18 +3369,79 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3376,18 +3369,79 @@ verify_types_in_gimple_assign (gimple stmt)
return false; return false;
} }
case COMPLEX_EXPR: case TRUTH_NOT_EXPR:
{ {
if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2)) }
{
error ("invalid operands in complex expression"); case NEGATE_EXPR:
return true; case ABS_EXPR:
} case BIT_NOT_EXPR:
case PAREN_EXPR:
case NON_LVALUE_EXPR:
case CONJ_EXPR:
case REDUC_MAX_EXPR:
case REDUC_MIN_EXPR:
case REDUC_PLUS_EXPR:
case VEC_UNPACK_HI_EXPR:
case VEC_UNPACK_LO_EXPR:
case VEC_UNPACK_FLOAT_HI_EXPR:
case VEC_UNPACK_FLOAT_LO_EXPR:
break;
default:
gcc_unreachable ();
}
/* For the remaining codes assert there is no conversion involved. */
if (!useless_type_conversion_p (lhs_type, rhs1_type))
{
error ("non-trivial conversion in unary operation");
debug_generic_expr (lhs_type);
debug_generic_expr (rhs1_type);
return true;
}
return false;
}
/* Verify a gimple assignment statement STMT with a binary rhs.
Returns true if anything is wrong. */
static bool
verify_gimple_assign_binary (gimple stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree lhs = gimple_assign_lhs (stmt);
tree lhs_type = TREE_TYPE (lhs);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs1_type = TREE_TYPE (rhs1);
tree rhs2 = gimple_assign_rhs2 (stmt);
tree rhs2_type = TREE_TYPE (rhs2);
if (!is_gimple_reg (lhs)
&& !(optimize == 0
&& TREE_CODE (lhs_type) == COMPLEX_TYPE))
{
error ("non-register as LHS of binary operation");
return true;
}
if (!TREE_CODE (lhs_type) == COMPLEX_TYPE if (!is_gimple_val (rhs1)
|| !(TREE_CODE (rhs1_type) == INTEGER_TYPE || !is_gimple_val (rhs2))
{
error ("invalid operands in binary operation");
return true;
}
/* First handle operations that involve different types. */
switch (rhs_code)
{
case COMPLEX_EXPR:
{
if (TREE_CODE (lhs_type) != COMPLEX_TYPE
|| !(INTEGRAL_TYPE_P (rhs1_type)
|| SCALAR_FLOAT_TYPE_P (rhs1_type)) || SCALAR_FLOAT_TYPE_P (rhs1_type))
|| !(TREE_CODE (rhs2_type) == INTEGER_TYPE || !(INTEGRAL_TYPE_P (rhs2_type)
|| SCALAR_FLOAT_TYPE_P (rhs2_type))) || SCALAR_FLOAT_TYPE_P (rhs2_type)))
{ {
error ("type mismatch in complex expression"); error ("type mismatch in complex expression");
...@@ -3400,26 +3454,13 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3400,26 +3454,13 @@ verify_types_in_gimple_assign (gimple stmt)
return false; return false;
} }
case CONSTRUCTOR:
{
/* In this context we know that we are on the RHS of an
assignment, so CONSTRUCTOR operands are OK. */
/* FIXME: verify constructor arguments. */
return false;
}
case LSHIFT_EXPR: case LSHIFT_EXPR:
case RSHIFT_EXPR: case RSHIFT_EXPR:
case LROTATE_EXPR: case LROTATE_EXPR:
case RROTATE_EXPR: case RROTATE_EXPR:
{ {
if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2)) if (!INTEGRAL_TYPE_P (rhs1_type)
{ || !INTEGRAL_TYPE_P (rhs2_type)
error ("invalid operands in shift expression");
return true;
}
if (!TREE_CODE (rhs1_type) == INTEGER_TYPE
|| !useless_type_conversion_p (lhs_type, rhs1_type)) || !useless_type_conversion_p (lhs_type, rhs1_type))
{ {
error ("type mismatch in shift expression"); error ("type mismatch in shift expression");
...@@ -3432,28 +3473,28 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3432,28 +3473,28 @@ verify_types_in_gimple_assign (gimple stmt)
return false; return false;
} }
case PLUS_EXPR: case VEC_LSHIFT_EXPR:
case MINUS_EXPR: case VEC_RSHIFT_EXPR:
{ {
if (POINTER_TYPE_P (lhs_type) if (TREE_CODE (rhs1_type) != VECTOR_TYPE
|| POINTER_TYPE_P (rhs1_type) || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
|| POINTER_TYPE_P (rhs2_type)) || (!INTEGRAL_TYPE_P (rhs2_type)
&& (TREE_CODE (rhs2_type) != VECTOR_TYPE
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs2_type))))
|| !useless_type_conversion_p (lhs_type, rhs1_type))
{ {
error ("invalid (pointer) operands to plus/minus"); error ("type mismatch in vector shift expression");
debug_generic_expr (lhs_type);
debug_generic_expr (rhs1_type);
debug_generic_expr (rhs2_type);
return true; return true;
} }
/* Continue with generic binary expression handling. */ return false;
break;
} }
case POINTER_PLUS_EXPR: case POINTER_PLUS_EXPR:
{ {
if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in pointer plus expression");
return true;
}
if (!POINTER_TYPE_P (rhs1_type) if (!POINTER_TYPE_P (rhs1_type)
|| !useless_type_conversion_p (lhs_type, rhs1_type) || !useless_type_conversion_p (lhs_type, rhs1_type)
|| !useless_type_conversion_p (sizetype, rhs2_type)) || !useless_type_conversion_p (sizetype, rhs2_type))
...@@ -3468,30 +3509,6 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3468,30 +3509,6 @@ verify_types_in_gimple_assign (gimple stmt)
return false; return false;
} }
case ADDR_EXPR:
{
tree op = TREE_OPERAND (rhs1, 0);
if (!is_gimple_addressable (op))
{
error ("invalid operand in unary expression");
return true;
}
if (!one_pointer_to_useless_type_conversion_p (lhs_type, TREE_TYPE (op))
/* FIXME: a longstanding wart, &a == &a[0]. */
&& (TREE_CODE (TREE_TYPE (op)) != ARRAY_TYPE
|| !one_pointer_to_useless_type_conversion_p (lhs_type,
TREE_TYPE (TREE_TYPE (op)))))
{
error ("type mismatch in address expression");
debug_generic_stmt (lhs_type);
debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op)));
return true;
}
return verify_types_in_gimple_reference (TREE_OPERAND (rhs1, 0));
}
case TRUTH_ANDIF_EXPR: case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR: case TRUTH_ORIF_EXPR:
gcc_unreachable (); gcc_unreachable ();
...@@ -3500,12 +3517,6 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3500,12 +3517,6 @@ verify_types_in_gimple_assign (gimple stmt)
case TRUTH_OR_EXPR: case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR: case TRUTH_XOR_EXPR:
{ {
if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in truth expression");
return true;
}
/* We allow any kind of integral typed argument and result. */ /* We allow any kind of integral typed argument and result. */
if (!INTEGRAL_TYPE_P (rhs1_type) if (!INTEGRAL_TYPE_P (rhs1_type)
|| !INTEGRAL_TYPE_P (rhs2_type) || !INTEGRAL_TYPE_P (rhs2_type)
...@@ -3521,108 +3532,226 @@ verify_types_in_gimple_assign (gimple stmt) ...@@ -3521,108 +3532,226 @@ verify_types_in_gimple_assign (gimple stmt)
return false; return false;
} }
case TRUTH_NOT_EXPR: case LT_EXPR:
{ case LE_EXPR:
if (!is_gimple_val (rhs1)) case GT_EXPR:
{ case GE_EXPR:
error ("invalid operand in unary not"); case EQ_EXPR:
return true; case NE_EXPR:
} case UNORDERED_EXPR:
case ORDERED_EXPR:
case UNLT_EXPR:
case UNLE_EXPR:
case UNGT_EXPR:
case UNGE_EXPR:
case UNEQ_EXPR:
case LTGT_EXPR:
/* Comparisons are also binary, but the result type is not
connected to the operand types. */
return verify_gimple_comparison (lhs_type, rhs1, rhs2);
/* For TRUTH_NOT_EXPR we can have any kind of integral case PLUS_EXPR:
typed arguments and results. */ case MINUS_EXPR:
if (!INTEGRAL_TYPE_P (rhs1_type) {
|| !INTEGRAL_TYPE_P (lhs_type)) if (POINTER_TYPE_P (lhs_type)
|| POINTER_TYPE_P (rhs1_type)
|| POINTER_TYPE_P (rhs2_type))
{ {
error ("type mismatch in not expression"); error ("invalid (pointer) operands to plus/minus");
debug_generic_expr (lhs_type);
debug_generic_expr (rhs1_type);
return true; return true;
} }
return false; /* Continue with generic binary expression handling. */
break;
} }
/* After gimplification we should not have any of these. */ case MULT_EXPR:
case ASM_EXPR: case TRUNC_DIV_EXPR:
case BIND_EXPR: case CEIL_DIV_EXPR:
case CALL_EXPR: case FLOOR_DIV_EXPR:
case COND_EXPR: case ROUND_DIV_EXPR:
case TREE_LIST: case TRUNC_MOD_EXPR:
case COMPOUND_EXPR: case CEIL_MOD_EXPR:
case MODIFY_EXPR: case FLOOR_MOD_EXPR:
case INIT_EXPR: case ROUND_MOD_EXPR:
case GOTO_EXPR: case RDIV_EXPR:
case LABEL_EXPR: case EXACT_DIV_EXPR:
case RETURN_EXPR: case MIN_EXPR:
case TRY_FINALLY_EXPR: case MAX_EXPR:
case TRY_CATCH_EXPR: case BIT_IOR_EXPR:
case EH_FILTER_EXPR: case BIT_XOR_EXPR:
case STATEMENT_LIST: case BIT_AND_EXPR:
{ case WIDEN_SUM_EXPR:
error ("tree node that should already be gimple."); case WIDEN_MULT_EXPR:
return true; case VEC_WIDEN_MULT_HI_EXPR:
} case VEC_WIDEN_MULT_LO_EXPR:
case VEC_PACK_TRUNC_EXPR:
case VEC_PACK_SAT_EXPR:
case VEC_PACK_FIX_TRUNC_EXPR:
case VEC_EXTRACT_EVEN_EXPR:
case VEC_EXTRACT_ODD_EXPR:
case VEC_INTERLEAVE_HIGH_EXPR:
case VEC_INTERLEAVE_LOW_EXPR:
/* Continue with generic binary expression handling. */
break;
case OBJ_TYPE_REF: default:
/* FIXME. */ gcc_unreachable ();
return false; }
default:; if (!useless_type_conversion_p (lhs_type, rhs1_type)
|| !useless_type_conversion_p (lhs_type, rhs2_type))
{
error ("type mismatch in binary expression");
debug_generic_stmt (lhs_type);
debug_generic_stmt (rhs1_type);
debug_generic_stmt (rhs2_type);
return true;
}
return false;
}
/* Verify a gimple assignment statement STMT with a single rhs.
Returns true if anything is wrong. */
static bool
verify_gimple_assign_single (gimple stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree lhs = gimple_assign_lhs (stmt);
tree lhs_type = TREE_TYPE (lhs);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs1_type = TREE_TYPE (rhs1);
bool res = false;
if (!useless_type_conversion_p (lhs_type, rhs1_type))
{
error ("non-trivial conversion at assignment");
debug_generic_expr (lhs_type);
debug_generic_expr (rhs1_type);
return true;
} }
/* Generic handling via classes. */ if (handled_component_p (lhs))
switch (TREE_CODE_CLASS (rhs_code)) res |= verify_types_in_gimple_reference (lhs);
/* Special codes we cannot handle via their class. */
switch (rhs_code)
{ {
case tcc_exceptional: /* for SSA_NAME */ case ADDR_EXPR:
case tcc_unary: {
if (!useless_type_conversion_p (lhs_type, rhs1_type)) tree op = TREE_OPERAND (rhs1, 0);
{ if (!is_gimple_addressable (op))
error ("non-trivial conversion at assignment"); {
debug_generic_expr (lhs_type); error ("invalid operand in unary expression");
debug_generic_expr (rhs1_type); return true;
return true; }
}
break;
case tcc_binary: if (!one_pointer_to_useless_type_conversion_p (lhs_type, TREE_TYPE (op))
if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2)) /* FIXME: a longstanding wart, &a == &a[0]. */
{ && (TREE_CODE (TREE_TYPE (op)) != ARRAY_TYPE
error ("invalid operands in binary expression"); || !one_pointer_to_useless_type_conversion_p (lhs_type,
return true; TREE_TYPE (TREE_TYPE (op)))))
} {
if (!useless_type_conversion_p (lhs_type, rhs1_type) error ("type mismatch in address expression");
|| !useless_type_conversion_p (lhs_type, rhs2_type)) debug_generic_stmt (lhs_type);
debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op)));
return true;
}
return verify_types_in_gimple_reference (op);
}
/* tcc_reference */
case COMPONENT_REF:
case BIT_FIELD_REF:
case INDIRECT_REF:
case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
case VIEW_CONVERT_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
case TARGET_MEM_REF:
if (!is_gimple_reg (lhs)
&& is_gimple_reg_type (TREE_TYPE (lhs)))
{ {
error ("type mismatch in binary expression"); error ("invalid rhs for gimple memory store");
debug_generic_stmt (lhs_type); debug_generic_stmt (lhs);
debug_generic_stmt (rhs1_type); debug_generic_stmt (rhs1);
debug_generic_stmt (rhs2_type);
return true; return true;
} }
break; return res || verify_types_in_gimple_reference (rhs1);
case tcc_reference: /* tcc_constant */
/* All tcc_reference trees are GIMPLE_SINGLE_RHS. Verify that case SSA_NAME:
no implicit type change happens here. */ case INTEGER_CST:
if (!useless_type_conversion_p (lhs_type, rhs1_type)) case REAL_CST:
case FIXED_CST:
case COMPLEX_CST:
case VECTOR_CST:
case STRING_CST:
return res;
/* tcc_declaration */
case CONST_DECL:
return res;
case VAR_DECL:
case PARM_DECL:
if (!is_gimple_reg (lhs)
&& !is_gimple_reg (rhs1)
&& is_gimple_reg_type (TREE_TYPE (lhs)))
{ {
error ("non-trivial conversion at assignment"); error ("invalid rhs for gimple memory store");
debug_generic_expr (lhs_type); debug_generic_stmt (lhs);
debug_generic_expr (rhs1_type); debug_generic_stmt (rhs1);
return true; return true;
} }
return verify_types_in_gimple_reference (rhs1); return res;
case tcc_comparison: case COND_EXPR:
return verify_gimple_comparison (lhs_type, rhs1, rhs2); case CONSTRUCTOR:
case OBJ_TYPE_REF:
case ASSERT_EXPR:
case WITH_SIZE_EXPR:
case EXC_PTR_EXPR:
case FILTER_EXPR:
case POLYNOMIAL_CHREC:
case DOT_PROD_EXPR:
case VEC_COND_EXPR:
case REALIGN_LOAD_EXPR:
/* FIXME. */
return res;
default:; default:;
} }
return false; return res;
} }
/* Verify the contents of a GIMPLE_ASSIGN STMT. Returns true when there
is a problem, otherwise false. */
static bool
verify_gimple_assign (gimple stmt)
{
switch (gimple_assign_rhs_class (stmt))
{
case GIMPLE_SINGLE_RHS:
return verify_gimple_assign_single (stmt);
case GIMPLE_UNARY_RHS:
return verify_gimple_assign_unary (stmt);
case GIMPLE_BINARY_RHS:
return verify_gimple_assign_binary (stmt);
default:
gcc_unreachable ();
}
}
/* Verify the contents of a GIMPLE_RETURN STMT. Returns true when there /* Verify the contents of a GIMPLE_RETURN STMT. Returns true when there
is a problem, otherwise false. */ is a problem, otherwise false. */
...@@ -3719,7 +3848,10 @@ verify_gimple_phi (gimple stmt) ...@@ -3719,7 +3848,10 @@ verify_gimple_phi (gimple stmt)
for (i = 0; i < gimple_phi_num_args (stmt); i++) for (i = 0; i < gimple_phi_num_args (stmt); i++)
{ {
tree arg = gimple_phi_arg_def (stmt, i); tree arg = gimple_phi_arg_def (stmt, i);
if (!is_gimple_val (arg)) if ((is_gimple_reg (gimple_phi_result (stmt))
&& !is_gimple_val (arg))
|| (!is_gimple_reg (gimple_phi_result (stmt))
&& !is_gimple_addressable (arg)))
{ {
error ("Invalid PHI argument"); error ("Invalid PHI argument");
debug_generic_stmt (arg); debug_generic_stmt (arg);
...@@ -3758,7 +3890,7 @@ verify_types_in_gimple_stmt (gimple stmt) ...@@ -3758,7 +3890,7 @@ verify_types_in_gimple_stmt (gimple stmt)
switch (gimple_code (stmt)) switch (gimple_code (stmt))
{ {
case GIMPLE_ASSIGN: case GIMPLE_ASSIGN:
return verify_types_in_gimple_assign (stmt); return verify_gimple_assign (stmt);
case GIMPLE_LABEL: case GIMPLE_LABEL:
return TREE_CODE (gimple_label_label (stmt)) != LABEL_DECL; return TREE_CODE (gimple_label_label (stmt)) != LABEL_DECL;
...@@ -3784,7 +3916,7 @@ verify_types_in_gimple_stmt (gimple stmt) ...@@ -3784,7 +3916,7 @@ verify_types_in_gimple_stmt (gimple stmt)
return false; return false;
case GIMPLE_CHANGE_DYNAMIC_TYPE: case GIMPLE_CHANGE_DYNAMIC_TYPE:
return (!is_gimple_reg (gimple_cdt_location (stmt)) return (!is_gimple_val (gimple_cdt_location (stmt))
|| !POINTER_TYPE_P (TREE_TYPE (gimple_cdt_location (stmt)))); || !POINTER_TYPE_P (TREE_TYPE (gimple_cdt_location (stmt))));
case GIMPLE_PHI: case GIMPLE_PHI:
......
...@@ -1137,7 +1137,7 @@ DEFTREECODE (VEC_INTERLEAVE_LOW_EXPR, "vec_interleavelow_expr", tcc_binary, 2) ...@@ -1137,7 +1137,7 @@ DEFTREECODE (VEC_INTERLEAVE_LOW_EXPR, "vec_interleavelow_expr", tcc_binary, 2)
outcome (0 for not taken and 1 for taken). Once the profile is guessed outcome (0 for not taken and 1 for taken). Once the profile is guessed
all conditional branches leading to execution paths executing the all conditional branches leading to execution paths executing the
PREDICT_EXPR will get predicted by the specified predictor. */ PREDICT_EXPR will get predicted by the specified predictor. */
DEFTREECODE (PREDICT_EXPR, "predict_expr", tcc_unary, 1) DEFTREECODE (PREDICT_EXPR, "predict_expr", tcc_expression, 1)
/* OPTIMIZATION_NODE. Node to store the optimization options. */ /* OPTIMIZATION_NODE. Node to store the optimization options. */
DEFTREECODE (OPTIMIZATION_NODE, "optimization_node", tcc_exceptional, 0) DEFTREECODE (OPTIMIZATION_NODE, "optimization_node", tcc_exceptional, 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment