Overflow handling

Mark Mitchell mark@codesourcery.com
Sun Oct 22 10:49:00 GMT 2000


>>>>> "Richard" == Richard Kenner <kenner@vlsi1.ultra.nyu.edu> writes:

    Richard> True.  Sorry.

    Richard> It's g++.brendan/crash30.C.

The problem here was that c_sizeof (the function that provides the
tree that results from a use of `sizeof' in the source program) was
returning an expression with TYPE_IS_SIZETYPE set.

That's incorrect; that function should be returning a size_t, not
GCC's internal notion of a "sizetype".  None of the special properties
of a sizetype hold of a `size_t', which is just an ordinary integer
type.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-10-22  Mark Mitchell  <mark@codesourcery.com>

	* tree.h (TYPE_IS_SIZETYPE): Add more documentation.

2000-10-22  Mark Mitchell  <mark@codesourcery.com>

	* typeck.c (c_sizeof): Return an expression of `size_t' type, 
	not one with TYPE_IS_SIZETYPE set.
	(dubious_conversion_warnings): Remove special-case code.

Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.205
diff -c -p -r1.205 tree.h
*** tree.h	2000/10/20 15:52:40	1.205
--- tree.h	2000/10/22 17:46:20
*************** struct tree_block
*** 949,957 ****
     its size.  */
  #define TYPE_NO_FORCE_BLK(NODE) (TYPE_CHECK (NODE)->type.no_force_blk_flag)
  
! /* In an INTEGER_TYPE, it means the type represents a size.  We use this
!    both for validity checking and to permit optimziations that are unsafe
!    for other types.  */
  #define TYPE_IS_SIZETYPE(NODE) \
    (INTEGER_TYPE_CHECK (NODE)->type.no_force_blk_flag)
  
--- 949,962 ----
     its size.  */
  #define TYPE_NO_FORCE_BLK(NODE) (TYPE_CHECK (NODE)->type.no_force_blk_flag)
  
! /* In an INTEGER_TYPE, it means the type represents a size.  We use
!    this both for validity checking and to permit optimizations that
!    are unsafe for other types.  Note that the C `size_t' type should
!    *not* have this flag set.  The `size_t' type is simply a typedef
!    for an ordinary integer type that happens to be the type of an
!    expression returned by `sizeof'; `size_t' has no special
!    properties.  Expressions whose type have TYPE_IS_SIZETYPE set are
!    always actual sizes.  */
  #define TYPE_IS_SIZETYPE(NODE) \
    (INTEGER_TYPE_CHECK (NODE)->type.no_force_blk_flag)
  
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.314
diff -c -p -r1.314 typeck.c
*** typeck.c	2000/10/20 17:51:52	1.314
--- typeck.c	2000/10/22 17:41:44
*************** c_sizeof (type)
*** 1548,1553 ****
--- 1548,1554 ----
       tree type;
  {
    enum tree_code code = TREE_CODE (type);
+   tree size;
  
    if (processing_template_decl)
      return build_min (SIZEOF_EXPR, sizetype, type);
*************** c_sizeof (type)
*** 1591,1601 ****
      }
  
    /* Convert in case a char is more than one unit.  */
!   return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
  		     size_int (TYPE_PRECISION (char_type_node)
  			       / BITS_PER_UNIT));
  }
  
  tree
  expr_sizeof (e)
       tree e;
--- 1592,1611 ----
      }
  
    /* Convert in case a char is more than one unit.  */
!   size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
  		     size_int (TYPE_PRECISION (char_type_node)
  			       / BITS_PER_UNIT));
+   /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
+      TYPE_IS_SIZETYPE means that certain things (like overflow) will
+      never happen.  However, this node should really have type
+      `size_t', which is just a typedef for an ordinary integer type.  */
+   size = fold (build1 (NOP_EXPR, c_size_type_node, size));
+   my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)), 
+ 		      20001021);
+   return size;
  }
  
+ 
  tree
  expr_sizeof (e)
       tree e;
*************** dubious_conversion_warnings (type, expr,
*** 6354,6367 ****
  			errtype, expr, type);
  	}
  
!       /* Suppress warning for a sizetype since we never used to issue it.
! 	 ??? This needs to be looked at more carefully someday.  */
!       if (TREE_CODE (expr) == INTEGER_CST
! 	  && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
! 	  && TYPE_IS_SIZETYPE (TREE_TYPE (expr)))
! 	TREE_OVERFLOW (expr) = TREE_CONSTANT_OVERFLOW (expr) = 0;
!       else
! 	overflow_warning (expr);
  
        if (TREE_CONSTANT (expr))
  	expr = fold (expr);
--- 6364,6370 ----
  			errtype, expr, type);
  	}
  
!       overflow_warning (expr);
  
        if (TREE_CONSTANT (expr))
  	expr = fold (expr);


More information about the Gcc-patches mailing list