This is the mail archive of the gcc-patches@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]

middle-end type-system: a verify_tree_type(s)


This is a start in doing strict type checking in the middle-end
from constraints documented in the tree.def file.

>From an instrumentation point of view, instrumenting buildN_stat
is most useful in pinpointing to the malicious creator.  Although
you won't get very far due to the C and C++ frontends using this
same machinery for internal trees.  Instrumenting fold to check
that we get correct types input to this critical function will
fail over, too, as f.i. the C frontend presents us with interesting
trees.  And pinpointing the creator of them is much harder if catching
them at fold time only.

But these routines served me quite useful during tree type fixing,
so you may find them useful, too ;)

Richard.


2005Jun01  Richard Guenther  <rguenth@gcc.gnu.org>

	* tree.c (verify_tree_type, verify_tree_types_1,
	verify_tree_types): New functions.
	* tree.h (verify_tree_type, verify_tree_types): Export.

Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.483
diff -c -3 -p -r1.483 tree.c
*** tree.c	1 Jun 2005 00:39:45 -0000	1.483
--- tree.c	1 Jun 2005 09:39:24 -0000
*************** walk_tree_without_duplicates (tree *tp,
*** 6781,6784 ****
--- 6781,6925 ----
    return result;
  }

+ /* Verify type correctness of the tree T without recursing into the
+    tree operands.  */
+
+ void
+ verify_tree_type (tree t)
+ {
+ /* Exchange this with __asm__("int3") to trap on ia32.  */
+ #define TREE_TYPE_ERROR gcc_unreachable ()
+
+   switch (TREE_CODE (t))
+     {
+       /* Trees with one operand.  */
+
+       case ADDR_EXPR:
+ 	if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) != ARRAY_TYPE
+ 	    && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t)))
+ 	    != TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (t, 0))))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case INDIRECT_REF:
+       case ALIGN_INDIRECT_REF:
+ 	if (TREE_OPERAND (t, 0)
+ 	    && TREE_TYPE (t) != TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case FIX_TRUNC_EXPR:
+       case FIX_CEIL_EXPR:
+       case FIX_FLOOR_EXPR:
+       case FIX_ROUND_EXPR:
+ 	if (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
+ 	    || ! SCALAR_FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case FLOAT_EXPR:
+ 	if (! SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))
+ 	    || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) != INTEGER_TYPE)
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case ABS_EXPR:
+ 	if (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
+ 	    && TREE_CODE (TREE_TYPE (t)) != REAL_TYPE)
+ 	  TREE_TYPE_ERROR;
+ 	/* Fall through.  */
+       case NEGATE_EXPR:
+ 	if (TREE_TYPE (t) != TREE_TYPE (TREE_OPERAND (t, 0)))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case BIT_NOT_EXPR:
+ 	if (TYPE_MODE (TREE_TYPE (t)) != TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+
+       /* Trees with two operands.  */
+
+       /* tcc_binary */
+
+       case LSHIFT_EXPR:
+       case RSHIFT_EXPR:
+       case LROTATE_EXPR:
+       case RROTATE_EXPR:
+ 	if (TREE_TYPE (t) != TREE_TYPE (TREE_OPERAND (t, 0)))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case BIT_IOR_EXPR:
+       case BIT_XOR_EXPR:
+       case BIT_AND_EXPR:
+ 	if (TYPE_MODE (TREE_TYPE (t)) != TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+ 	    || TYPE_MODE (TREE_TYPE (t)) != TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 1))))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       case PLUS_EXPR:
+       case MINUS_EXPR:
+       case MULT_EXPR:
+       case TRUNC_DIV_EXPR:
+       case CEIL_DIV_EXPR:
+       case FLOOR_DIV_EXPR:
+       case ROUND_DIV_EXPR:
+       case TRUNC_MOD_EXPR:
+       case CEIL_MOD_EXPR:
+       case FLOOR_MOD_EXPR:
+       case ROUND_MOD_EXPR:
+       case RDIV_EXPR:
+       case EXACT_DIV_EXPR:
+       case MIN_EXPR:
+       case MAX_EXPR:
+ 	if (TREE_TYPE (t) != TREE_TYPE (TREE_OPERAND (t, 0))
+ 	    || TREE_TYPE (t) != TREE_TYPE (TREE_OPERAND (t, 1)))
+ 	  TREE_TYPE_ERROR;
+ 	break;
+
+       /* tcc_reference */
+       case MISALIGNED_INDIRECT_REF:
+ 	if (TREE_TYPE (t) != TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)))
+ 	    || TREE_CODE (TREE_OPERAND (t, 1)) != INTEGER_CST)
+ 	  TREE_TYPE_ERROR;
+
+
+       /* Trees with three operands.  */
+
+       case COMPONENT_REF:
+ 	if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) != RECORD_TYPE
+ 	     && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) != UNION_TYPE
+ 	     && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) != QUAL_UNION_TYPE)
+ 	    || TREE_CODE (TREE_OPERAND (t, 1)) != FIELD_DECL
+ 	    || TREE_TYPE (t) != TREE_TYPE (TREE_OPERAND (t, 1)))
+ 	  TREE_TYPE_ERROR;
+         break;
+
+
+       default:
+ 	;
+     }
+
+ #undef TREE_TYPE_ERROR
+ }
+
+ static tree
+ verify_tree_types_1 (tree *t, int *walk_subtrees ATTRIBUTE_UNUSED,
+ 		     void *arg ATTRIBUTE_UNUSED)
+ {
+   verify_tree_type (*t);
+   return *t;
+ }
+
+ /* Verify type correctness of the tree T recursively.  */
+
+ void
+ verify_tree_types (tree t)
+ {
+   walk_tree_without_duplicates (&t, verify_tree_types_1, NULL);
+ }
+
+
  #include "gt-tree.h"
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.731
diff -c -3 -p -r1.731 tree.h
*** tree.h	1 Jun 2005 00:39:46 -0000	1.731
--- tree.h	1 Jun 2005 09:39:24 -0000
*************** extern tree get_base_address (tree t);
*** 3988,3991 ****
--- 3988,3995 ----
  /* In tree-vectorizer.c.  */
  extern void vect_set_verbosity_level (const char *);

+ /* Verify types of trees.  */
+ extern void verify_tree_type (tree t);
+ extern void verify_tree_types (tree t);
+
  #endif  /* GCC_TREE_H  */


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