This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[RFC] Tightening up the type system
- From: Diego Novillo <dnovillo at redhat dot com>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 28 Sep 2004 11:35:58 -0400
- Subject: [RFC] Tightening up the type system
- Organization: Red Hat Canada
Over the last few days I have found various places in the optimizers
where binary expressions and assignments had operands of non-compatible
types.
For instance, out of the gimplifier we were getting an assignment like
'iftmp.256 = 0B', where iftmp.256 was 'some_type *' and 0B was
'void *'.
We would then fail to propagate iftmp.256 because its constant value is
of the wrong type (may_propagate_copy would reject it). This was caused
by tree_ssa_useless_type_conversion_1 stripping a (void *) from the
original FE trees.
In other cases we were generating boolean 'true'/'false' constants when
we really needed to be generating integer values (because of ABI
requirements).
So, as an experiment I added the attached patch to the statement
verifier. Needless to say, we ICE almost immediately. I first had to
exclude all the shift operators (tree.def states that the types may be
different). But now I am getting a failure building libgcov.o on this
assignment
result = D.4720 + &__gcov_var.buffer[0];
(gdb) ptu t.exp.operands[0].common.type
const gcov_unsigned_t *
(gdb) ptu t.exp.operands[1].common.type
gcov_unsigned_t *
lang_hook.compatible_types_p is rejecting those two types because of the
const qualifier.
My question to the FE folks is: what are the right semantics for
checking MODIFY_EXPR? Is compatible_types_p too strict? Should we have
had a cast operation in the above assignment?
Not having the right types is increasingly getting in the way of the
optimizers because we use compatible_types_p quite often to validate
propagation opportunities.
In fact, I would like to get to the point where we can simply call
'gcc_assert (lang_hook.compatible_types_p (dest, orig))' when doing
propagation. Ideally, all the necessary type conversions should be
exposed in the IL.
Thanks. Diego.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.59
diff -d -u -p -r2.59 tree-cfg.c
--- tree-cfg.c 28 Sep 2004 07:59:50 -0000 2.59
+++ tree-cfg.c 28 Sep 2004 15:27:58 -0000
@@ -3062,6 +3062,7 @@ static tree
verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
tree t = *tp, x;
+ enum tree_code code;
if (TYPE_P (t))
*walk_subtrees = 0;
@@ -3074,7 +3075,8 @@ verify_expr (tree *tp, int *walk_subtree
&& !is_gimple_val (TREE_OPERAND (t, N))) \
{ error (MSG); return TREE_OPERAND (t, N); }} while (0)
- switch (TREE_CODE (t))
+ code = TREE_CODE (t);
+ switch (code)
{
case SSA_NAME:
if (SSA_NAME_IN_FREE_LIST (t))
@@ -3092,6 +3094,13 @@ verify_expr (tree *tp, int *walk_subtree
error ("GIMPLE register modified with BIT_FIELD_REF");
return t;
}
+
+ if (!lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (t, 0)),
+ TREE_TYPE (TREE_OPERAND (t, 1))))
+ {
+ error ("Incompatible types in an assignment");
+ return t;
+ }
break;
case ADDR_EXPR:
@@ -3218,6 +3227,17 @@ verify_expr (tree *tp, int *walk_subtree
case BIT_AND_EXPR:
CHECK_OP (0, "Invalid operand to binary operator");
CHECK_OP (1, "Invalid operand to binary operator");
+
+ if (code != LSHIFT_EXPR
+ && code != RSHIFT_EXPR
+ && code != LROTATE_EXPR
+ && code != RROTATE_EXPR
+ && !lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (t, 0)),
+ TREE_TYPE (TREE_OPERAND (t, 1))))
+ {
+ error ("Incompatible types in a binary operator");
+ return t;
+ }
break;
default: