This splits out some small chunks from the patch killing 
TYPE_IS_SIZETYPE.  It introduces a helper function that
performs object-size checks and uses it in the few places
that would need adjustments when host_integerp is no longer
appropriate for verifying that the size fits in half of the
address-space.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

--

Eric, this starts the series of getting rid of TYPE_IS_SIZETYPE.
This patch will break Ada bootstrap (fixed by subsequent patches),
because copy_and_substitute_in_size () will sometimes (in this
case for the secondary stack size) compute a constant TYPE_SIZE_UNIT
with TREE_OVERFLOW set (compiling s-secsta.adb).  With the theory that
sizetypes cannot have overflow this looks like a latent bug somewhere in
the construction of the expression that leads to it.  When sizetypes
are finally unsigned the overflow bit will not be set anymore and
this bug does not trigger.

Happens when substitute_in_expr with
exp = (sizetype) ((bitsizetype) -<PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.first + 10241)
f = first
r = 1
we then convert bitsizetype 0x100002800 to sizetype via
fold_convert_const_int_from_int (this is -m32 multilib), which
leads to an overflowed value.  Not sure how we arrive at this
call of substitute_in_expr as the original expression we substitute in
is

((sizetype) (_GLOBAL.SZ4_system.secondary_stack (<PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.first) /[cl] 8) + 15 & -16) + 16

and thus the bitsize quantity _GLOBAL.SZ4_system.secondary_stack 
(<PLACEHOLDER_EXPR struct
system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct
system__secondary_stack__chunk_id>.first) is first divided by 8
and _then_ converted to sizetype.  I suspect some existing bug
in some re-association.  It's appearantly not

2011-09-04  Richard Guenther  <rguent...@suse.de>

        Revert
        2011-08-31  Richard Guenther  <rguent...@suse.de>

        * fold-const.c (extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE
        special-casing.

though.

I'm not sure how much I need to care for Ada at this point, and I am
definitely wanting to kill off TYPE_IS_SIZETYPE and sizetypes 
sign-extending.  That's a definite prerequesite to continue on
no-undefined-overflow.

--

Thanks,
Richard.

2012-03-06  Richard Guenther  <rguent...@suse.de>

        * tree.c (valid_constant_size_p): New function.
        * tree.h (valid_constant_size_p): Declare.
        * cfgexpand.c (expand_one_var): Adjust check for too large
        variables by using valid_constant_size_p.
        * varasm.c (assemble_variable): Likewise.

        c/
        * c-decl.c (grokdeclarator): Properly check for sizes that
        cover more than half of the address-space.

        cp/
        * decl.c (grokdeclarator): Properly check for sizes that
        cover more than half of the address-space.

Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c       2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/tree.c    2011-09-05 15:51:20.000000000 +0200
*************** compare_tree_int (const_tree t, unsigned
*** 6782,6787 ****
--- 6774,6793 ----
      return 1;
  }
  
+ /* Return true if SIZE represents a constant size that is in bounds of
+    what the middle-end and the backend accepts (covering not more than
+    half of the address-space).  */
+ 
+ bool
+ valid_constant_size_p (const_tree size)
+ {
+   if (! host_integerp (size, 1)
+       || TREE_OVERFLOW (size)
+       || tree_int_cst_sign_bit (size) != 0)
+     return false;
+   return true;
+ }
+ 
  /* Return true if CODE represents an associative tree code.  Otherwise
     return false.  */
  bool
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c     2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/varasm.c  2011-09-05 16:03:53.000000000 +0200
*************** assemble_variable (tree decl, int top_le
*** 1980,1986 ****
      return;
  
    if (! dont_output_data
!       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
      {
        error ("size of variable %q+D is too large", decl);
        return;
--- 1980,1986 ----
      return;
  
    if (! dont_output_data
!       && ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
      {
        error ("size of variable %q+D is too large", decl);
        return;
Index: trunk/gcc/c-decl.c
===================================================================
*** trunk.orig/gcc/c-decl.c     2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/c-decl.c  2011-09-05 15:51:20.000000000 +0200
*************** grokdeclarator (const struct c_declarato
*** 5708,5719 ****
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        if (name)
        error_at (loc, "size of array %qE is too large", name);
--- 5708,5719 ----
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        if (name)
        error_at (loc, "size of array %qE is too large", name);
Index: trunk/gcc/cp/decl.c
===================================================================
*** trunk.orig/gcc/cp/decl.c    2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/cp/decl.c 2011-09-05 15:51:20.000000000 +0200
*************** grokdeclarator (const cp_declarator *dec
*** 9505,9516 ****
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
--- 9505,9516 ----
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c  2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/cfgexpand.c       2011-09-05 15:51:20.000000000 +0200
*************** expand_one_var (tree var, bool toplevel,
*** 1067,1074 ****
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
      {
        if (really_expand)
        {
          error ("size of variable %q+D is too large", var);
--- 1067,1075 ----
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (! valid_constant_size_p (DECL_SIZE_UNIT (var)))
      {
+       /* Reject variables which cover more than half of the address-space.  */
        if (really_expand)
        {
          error ("size of variable %q+D is too large", var);
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h       2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/tree.h    2011-09-05 15:51:20.000000000 +0200
*************** extern bool tree_expr_nonnegative_warnv_
*** 4388,4393 ****
--- 4388,4394 ----
  extern bool may_negate_without_overflow_p (const_tree);
  extern tree strip_array_types (tree);
  extern tree excess_precision_type (tree);
+ extern bool valid_constant_size_p (const_tree);
  
  /* Construct various nodes representing fract or accum data types.  */
  

Reply via email to