This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Tightening up the type system


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:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]